Изменение коммитов в Git

    Это пост для тех, кто начинает работу с Git. Все, что здесь написано по частям можно найти в многочисленных простынях о Git на Хабре. Но я подумал, что неплохо было бы иметь отдельный предельно понятный топик, который бы гуглился по запросу «git изменение коммитов».

    Изменение последнего коммита


    Если вы что-либо недоглядели в последнем коммите, то отредактировать его не составит никакого труда. Все, что нужно это добавить изменения обычным образом:

    git add .
    

    Затем закоммитить изменения с параметром --amend (amend /əˈmɛnd/ — вносить поправки, исправлять, улучшать):

    git commit --amend
    

    Изменение названия последнего коммита


    То же самое, с той лишь разницей что нет необходимости добавлять файлы в коммит. Просто укажите новое название:

    git commit --amend -m "Новое название"
    

    Изменение НЕ последнего коммита


    Тут чуть посложнее, сделайте для начала два коммита, в моем примере они будут называться С1 и С2:
    image

    Для начала выполняем:
    git rebase --interactive 
    # короткая версия: git rebase -i
    

    Откроется редактор, в котором вы можете указать что хотите сделать:
    image

    Как видите, git rebase -i может послужить когда нужно
    • r reword переименовать коммит
    • e edit изменить коммит
    • s squash склеить два или больше коммитов (squash /skwɒʃ/ — втиснуть, сжимать, тыква :) )

    Рядом с коммитом С1 вместо pick впишите e для редактирования коммита или r для переименования. Сохранив файл, вы увидите подсказку от Git:
    image

    Разберемся подробнее что произошло. Мы переместились на коммит С1, «спрыгнув» с ветки master. Это можно проверить, запустив:
    git branch
    

    В ответ получим:
    * (no branch, rebasing master)
      master
    

    Дальше, как первой части поста где мы меняли последний коммит, делаем изменения и добавляем их:
    git add .
    

    и коммитим с параметром --amend:
    git commit --amend
    

    После успешного коммита, следуя подсказке (чуть выше на скриншоте), выполняем:
    git rebase --continue
    

    Тем самым мы возвратимся на ветку master с измененным коммитом, что и требовалось.

    Пост получился короткий и, надеюсь, ясный. Commit early, commit often.
    Поделиться публикацией

    Похожие публикации

    Комментарии 21

      +25
      Главное в туториалах по rebase — не делайте этого с комитами, доступными не только вам.
        +7
        То же касается и amend и вообще любых правок репозитория после того как сделан git push. Кстати, об этом неплохо-бы написать в статье, пусть даже многие сервера и не принимают такие правки.
          0
          А ещё не делать git pull --rebase после мержа веток.
            –3
            А если надо? Можно прекрасно сделать rebase даже с общими ветками, и даже без последствий типа merge у остальных.
              0
              Зачем надо? Либо остальные тоже будут вынуждены править историю, либо такие манипуляции сильнее испортят историю.
                +1
                Это слишком большой холивар merge vs rebase.
                Я лишь сказал что можно это сделать легко без последствий, даже если работаешь группой в одной ветке.
                Зачем надо или зачем не надо, это другой вопрос.
            +5
            Извините, но капитанская статья… Очень хочется увидеть примеров вышеописаных действий. Вот допустим я нагадил накомитил в мастер, опомнился, захотел вынести в ветку — а не тут то было, пуш уже сделан.
            Допустим вариант с анпабликом ветки, исправления косяков, и обратный паблик. Просто я не особо много в команде успел поработать, но думаю что в команде просто так в мастер не покомитишь, а в своей ветке сколько угодно можешь исправлять. Или я не прав?
              +1
              В таких случаях лучше сделать git revert, я думаю. Хотя еще лучше в своей ветке работать, тогда таких ситуаций возникать не должно.
                +9
                Кстати хорошая идея статьи для хабра — «Что делать, если вы нагадилинакоммитили в мастер».
                  +1
                  В разделе мана про теги есть фраза о том, как переименовать тег: "Just admit you screwed up, and use a different name."
                  Думаю, эта статья должна начинаться так же.
                    0
                    «Just admit you screwed up, and use a different job
                +3
                А самое интересное начинается, когда начинаются конфликты.

                Ещё rebase может послужить, когда нужно поменять коммиты местами.
                  +3
                  Interactive rebase вообще мощная штука.

                  Я им, как правило пользуюсь для подготовки истории следующими способами:
                  — изменение порядка коммитов,
                  — слияние/разделение коммитов (чтобы в репозитории оставались только рабочие коммиты),
                  — ради переработки сообщений (в частности, с описанием номера исправленного недостатка для redmine).

                  Реже, чтобы поправить метаданные какого-нибудь коммита в середине (например, если забыл указать автора какого-нибудь патча).
                  +2
                  Вместо рекомендуемой автором пары
                  git add .
                  git commit --amend

                  достаточно одной команды:
                  git commit -a --amend
                    +1
                    Я бы порекомендовал вменяемый gui-клиент типа git extensions, где можно неспеша посмотреть на изменения, добавить и закоммитить без использования консоли. Гитом можно эффективно пользоваться из UI клиента.
                      +2
                      Я обычно пользуюсь tig (git ncurses frontend). Добротный консольный клиент с хорошим текстовым gui (tui).

                      Хотя большую часть действий я выполняю из командной строки. Tig, в основном, используется для быстрой навигации по изменениям.
                      +2
                      разница есть, git add. имеет локальную область действия, начиная от текущего каталога, плюсом добавит untracked, если есть
                      git commit -a предложит закоммитить только измененые по всему реапозиторию, вне зависимости от относительного пути
                      0
                      Хорошее правило, — не использовать git commit -a или git add .. Чтобы лишнего не коммитить, лучше указывать список файлов явно. Если ветка своя, то можно так и не париться.
                        +1
                        Я люблю использовать git add -p, реже git add -i. Заодно и беглый обзор изменений.
                          +2
                          А у нас git add -p — это категорическое требование к разработчикам :)
                        –1
                        Прошелся по хабу GIT, и к своему удивлению заметил, что мало статей собственно о теме.
                        На счет данного поста — всегда обходился soft reset-ом, но это явно лучше, практически ничего не меняя (не убивая существующих коммитов) делаешь маленькие правки. И вроде знал о такой возможности, но руки не доходили почитать мануал. Спасибо автору, занес в избранное.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое