Да ли сте икада дошли у ситуацију да требате преправити последњи комит, променити редослед или спојити више комита у један? Ако сте тада одустали и мислили да је то немогуће, наставите читати и научићете како пребродити ове „проблеме“.

Пре него што почнемо хтео бих истаћи опасност мењања комита који се већ налазе на Git репоу. У случају да је неко од ваших колега имао свучен репо, или још горе – да је активно радио на њему, може доћи до „главобоље“ од конфликта. Наравно, ни то није нерешиво те уз помоћ cherry-pick наредбе можете изолвати измене на другу грану, обрисати и поново свући конфликтну грану те измене вратити на њу.

Упозорење

Мењање локалних комита је безболно и не захтева посебне вештине, поготово ако се ради о последњем комиту.

Да промените поруку последњег комита можете искористити наредбу:

$ git commit --amend --no-edit

Ипак, ако желите променити и садржај онда изоставите параметар –no-edit

$ git commit --amend

Да бисте избегли муке које са собом доноси vim едитор саветујем вам да као подразумевани Git едитор поставите nano:

git config –global core.editor „nano“

Мењање више комита је нешто већи посао, али опет веома лако изводљив. Да бисте обухватили више од једног комита можете искористити rebase наредбу и то следеће синтаксе:

$ git rebase -i HEAD~{number_of_commits}

{number_of_commits} је потребно заменити бројем комита који ће бити захваћени. На пример, ако желимо изменити први од два комита извршићемо:

$ git rebase -i HEAD~2

Приликом извршавања команде отвориће нам се текстуални едитор са списком комита које смо обухватили:

1| pick {SHA_of_first_commit} {message_of_first_commit}
2| pick {SHA_of_second_commit} {message_of_second_commit}
n| означава број линије у едитору

Као што можете приметити редослед је обрнут у односу на git log команду, где се прво приказујују последњи комити (у овом случају би на првом месту био други комит).

pick, на почетку линије, означава шта желимо урадити са комитом. Неке од опција које можемо изабрати су:

pick - укључити комит

reword - сличан pick опцији, али ће се rebase зауставити те ћемо моћи да променимо поруку комита (садржај комита остаје исти)

edit - изменити комит, његову поруку и садржај

squash - спојити са претходним

drop - избрисати комит

Линије у фајлу се извршавају од врха до дна те ако желимо променити распоред комита то можемо учинити мењањем редоследа линија.

У нашем случају промена првог комита би ишла овим током:

// Покрећемо rebase над два претходна комита
$ git rebase -i HEAD~2

// Отвара се текстуални едитор
1| pick {SHA_of_first_commit} {message_of_first_commit}
2| pick {SHA_of_second_commit} {message_of_second_commit}

// Мењамо садржај тако да означавамо први комит за измену
1| edit {SHA_of_first_commit} {message_of_first_commit}
2| pick {SHA_of_second_commit} {message_of_second_commit}

// Након чувања фајла rebase поступак је покренут и git нас враћа у стање првог комита, где можемо променити поруку и код помоћу команде са почетка текста
$ git commit --amend

// После измена потребно је наставити rebase
git rebase --continue

Могуће је и поделити комит у више њих. На пример, ако желимо први комит поделити у два комита.

// Покрећемо rebase над два претходна комита
$ git rebase -i HEAD~2

// Отвара се текстуални едитор
1| pick {SHA_of_first_commit} {message_of_first_commit}
2| pick {SHA_of_second_commit} {message_of_second_commit}

// Мењамо садржај тако да означавамо први комит за измену
1| edit {SHA_of_first_commit} {message_of_first_commit}
2| pick {SHA_of_second_commit} {message_of_second_commit}

// Након чувања фајла rebase поступак је покренут и git нас враћа у стање првог комита

// Распакујемо измене комита (претпоставимо да измене чине фајлови a.py и b.py)
$ git reset HEAD^

// Додајемо a.py и комитујемо
$ git add a.py
$ git commit -m "Added a.py"

// Додајемо b.py и комитујемо
$ git add b.py
$ git commit -m "Added b.py"

// Настављамо rebase
git rebase --continue

Као што сам рекао комите није препоручљиво мењати ако се већ налазе у репоу. Ипак, могуће је и поступак је исти, с тим да при пушовању на репо морамо додати force опцију:

git push origin {branch_name} --force