Как изменить существующие невыдвинутые коммиты?
Я написал неправильную вещь в сообщении фиксации. Кроме того, я забыл включить некоторые файлы.
Как я могу изменить сообщение / файлы фиксации? Коммит еще не был передан.
27 ответов
Изменение самого последнего сообщения о коммите
git commit --amend
откроет ваш редактор, позволяющий вам изменить сообщение о коммите самого последнего коммита. Кроме того, вы можете установить сообщение фиксации непосредственно в командной строке с помощью:
git commit --amend -m "New commit message"
… Однако, это может сделать сообщения о многострочной фиксации или небольшие исправления более трудоемкими для ввода.
Прежде чем делать это, убедитесь, что у вас нет изменений рабочей копии, иначе они будут зафиксированы. (Не внесенные изменения не будут зафиксированы.)
Изменение сообщения коммита, который вы уже отправили в удаленную ветку
Если вы уже выдвинули свой коммит в удаленную ветку, то вам нужно принудительно протолкнуть коммит с помощью:
git push <remote> <branch> --force
# Or
git push <remote> <branch> -f
Предупреждение: принудительное нажатие перезапишет удаленную ветвь с состоянием вашей локальной ветки. Если в удаленной ветке есть коммиты, которых нет в вашей локальной ветке, вы потеряете эти коммиты.
Предупреждение: будьте осторожны при внесении изменений в коммиты, которыми вы уже поделились с другими людьми. Внесение изменений в коммиты по существу переписывает их с разными идентификаторами SHA, что создает проблему, если у других людей есть копии старых коммитов, которые вы переписали. Любой, у кого есть копия старого коммита, должен будет синхронизировать свою работу с вновь перезаписанным коммитом, что иногда может быть затруднено, поэтому убедитесь, что вы координируете действия с другими при попытке переписать историю общего коммита, или просто избегайте перезаписи общих коммитов в целом.
Используйте интерактивный ребаз
Другим вариантом является использование интерактивной перебазировки.
Это позволяет вам редактировать любое сообщение, которое вы хотите обновить, даже если это не последнее сообщение.
Чтобы сделать git squash, выполните следующие действия:
// X is the number of commits to the last commit you want to be able to edit
git rebase -i HEAD~X
Как только вы раздавите свои коммиты - выберите e/r
для редактирования сообщения
Важное замечание об интерактивной перебазировке
Когда вы используете git rebase -i HEAD~X
может быть больше, чем X
совершает. Git "соберет" все коммиты за последний X
коммиты, и если где-то между этими диапазонами произошло слияние, вы также увидите все коммиты, поэтому результатом будет X+.
Хороший совет:
Если вам нужно сделать это для более чем одной ветви, и вы можете столкнуться с конфликтами при внесении изменений в контент, настройте git rerere
и пусть git автоматически разрешит эти конфликты для вас.
Документация
Если фиксация, которую вы хотите исправить, не самая последняя:
git rebase --interactive $parent_of_flawed_commit
Если вы хотите исправить несколько некорректных коммитов, передайте родителю самого старого из них.
Появится редактор со списком всех коммитов, начиная с того, который вы дали.
- + Изменить
pick
вreword
(или на старых версиях Git, чтобыedit
) перед любыми коммитами, которые вы хотите исправить. - После сохранения Git воспроизведет перечисленные коммиты.
- + Изменить
Для каждого коммита, который вы хотите перефразировать, Git вернет вас обратно в ваш редактор. Для каждого коммита, который вы хотите редактировать, Git помещает вас в оболочку. Если вы в оболочке:
- Измените коммит любым удобным вам способом.
git commit --amend
git rebase --continue
Большая часть этой последовательности будет объяснена вам при выводе различных команд. Это очень просто, вам не нужно запоминать это - просто помните, что git rebase --interactive
позволяет корректировать коммиты независимо от того, как давно они были.
Обратите внимание, что вы не захотите изменять коммиты, которые вы уже выдвинули. Или, может быть, так и есть, но в этом случае вам придется позаботиться о том, чтобы общаться со всеми, кто мог выполнить ваши коммиты и поработать над ними. Как я могу восстановить / повторно синхронизировать после того, как кто-то отправит ребаз или сброс в опубликованную ветку?
Чтобы изменить предыдущий коммит, внесите необходимые изменения и выполните эти изменения, а затем выполните команду
git commit --amend
Это откроет файл в вашем текстовом редакторе, представляющий ваше новое сообщение коммита. Он начинается с текста из вашего старого сообщения коммита. Измените сообщение о коммите как хотите, затем сохраните файл и выйдите из редактора, чтобы завершить работу.
Чтобы изменить предыдущую фиксацию и сохранить то же сообщение журнала, запустите
git commit --amend -C HEAD
Чтобы исправить предыдущий коммит, удалив его полностью, запустите
git reset --hard HEAD^
Если вы хотите отредактировать более одного сообщения о коммите, запустите
git rebase -i HEAD~commit_count
(Замените commit_count на количество коммитов, которые вы хотите редактировать.) Эта команда запускает ваш редактор. Пометьте первый коммит (тот, который вы хотите изменить) как "edit" вместо "pick", затем сохраните и выйдите из вашего редактора. Сделайте изменения, которые вы хотите зафиксировать, а затем выполните
git commit --amend
git rebase --continue
Примечание. Вы также можете "внести необходимые изменения" в редакторе, открытом git commit --amend
Как уже упоминалось, git commit --amend
способ перезаписать последний коммит Одно замечание: если вы хотите перезаписать файлы, команда
git commit -a --amend -m "My new commit message"
Вы также можете использовать Git filter-branch
для этого.
git filter-branch -f --msg-filter "sed 's/errror/error/'" $flawed_commit..HEAD
Это не так просто, как тривиальное git commit --amend
, но это особенно полезно, если у вас уже есть некоторые слияния после вашего сообщения об ошибке.
Обратите внимание, что это попытается переписать КАЖДЫЙ коммит между HEAD
и ошибочный коммит, так что вы должны выбрать свой msg-filter
команда очень мудрая;-)
Я предпочитаю этот путь.
git commit --amend -c <commit ID>
В противном случае будет новый коммит с новым идентификатором коммита
Если вы используете инструмент Git GUI, есть кнопка с названием Изменить последний коммит. Нажмите на эту кнопку, и она покажет ваши последние файлы коммита и сообщение. Просто отредактируйте это сообщение, и вы сможете зафиксировать его с новым сообщением.
Или используйте эту команду из консоли / терминала:
git commit -a --amend -m "My new commit message"
Вы можете использовать Git ReBasing. Например, если вы хотите изменить обратно, чтобы зафиксировать bbc643cd, запустите
$ git rebase bbc643cd^ --interactive
В редакторе по умолчанию измените 'pick' на 'edit' в строке, фиксацию которой вы хотите изменить. Сделайте свои изменения и затем поставьте их на
$ git add <filepattern>
Теперь вы можете использовать
$ git commit --amend
изменить коммит, и после этого
$ git rebase --continue
вернуться к предыдущему главному коммиту.
Если вы хотите изменить только последнее сообщение о коммите, сделайте:
git commit --amend
Это приведет вас к вашему текстовому редактору и позволит вам изменить последнее сообщение о коммите.
Если вы хотите изменить последние 3 сообщения фиксации или любое из сообщений фиксации до этой точки, укажите
HEAD~3
кgit rebase -i
команда:git rebase -i HEAD~3
Если вам нужно изменить старое сообщение о коммите в нескольких ветвях (т. Е. Коммит с ошибочным сообщением присутствует в нескольких ветвях), вы можете использовать:
git filter-branch -f --msg-filter \
'sed "s/<old message>/<new message>/g"' -- --all
Git создаст временный каталог для перезаписи и дополнительно создаст резервную копию старых ссылок в refs/original/
,
-f
обеспечит выполнение операции. Это необходимо, если временный каталог уже существует или если ссылки уже хранятся вrefs/original
, Если это не так, вы можете сбросить этот флаг.--
отделяет параметры ветви фильтра от параметров ревизии.--all
убедится, что все ветки и теги переписаны.
Благодаря резервному копированию ваших старых ссылок, вы можете легко вернуться к состоянию перед выполнением команды.
Дескать, вы хотите восстановить своего мастера и получить к нему доступ в ветке old_master
:
git checkout -b old_master refs/original/refs/heads/master
Если это ваш последний коммит, просто измените коммит:
git commit --amend -o -m "New commit message"
(с использованием -o
( --only
), чтобы убедиться, что вы изменили только сообщение коммита)
Если это скрытый коммит, используйте потрясающую интерактивную ребазу:
git rebase -i @~9 # Show the last 9 commits in a text editor
Найдите коммит, который хотите, измените pick
в r
(reword
) и сохраните и закройте файл. Готово!
Миниатюрный учебник vim (или, как сделать перебаз только с 8 нажатиями клавиш 3j
cw
r
Esc ZZ
):
- Бежать
vimtutor
Если у вас есть время h
j
k
l
соответствуют клавишам перемещения ← ↓ ↑ →- Все команды могут иметь префикс "диапазон", например
3j
движется вниз на 3 строки i
для входа в режим вставки - введенный вами текст появится в файле- Esc или Ctrl
c
выйти из режима вставки и вернуться в "нормальный" режим u
отменить- Ctrl
r
переделать dd
,dw
,dl
удалить строку, слово или букву соответственноcc
,cw
,cl
изменить строку, слово или букву соответственно (так же, какdd
i
)yy
,yw
,yl
скопировать ("yank") строку, слово или букву соответственноp
или жеP
вставить после или до текущей позиции, соответственно:w
Введите, чтобы сохранить (записать) файл:q!
Войти, чтобы выйти без сохранения:wq
Введите илиZZ
сохранить и выйти
Если вы много редактируете текст, переключитесь на раскладку клавиатуры Dvorak, научитесь печатать на клавиатуре и изучите vim. Стоит ли усилий? Да.
ProTip ™: не бойтесь экспериментировать с "опасными" командами, которые переписывают историю * - Git по умолчанию не удаляет ваши коммиты в течение 90 дней; вы можете найти их в reflog:
$ git reset @~3 # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started
* Остерегайтесь вариантов, таких как --hard
а также --force
хотя - они могут отбросить данные.
* Кроме того, не переписывайте историю ни в каких ветвях, над которыми вы сотрудничаете.
Использование
git commit --amend
Чтобы понять это подробно, отличный пост - 4. Переписывание Git History. Это также говорит о том, когда не использовать git commit --amend
,
изменить
У вас есть несколько вариантов здесь. Ты можешь сделать
git commit --amend
пока это ваш последний коммит.
Интерактивная перебазировка
В противном случае, если это не ваш последний коммит, вы можете сделать интерактивный ребаз,
git rebase -i [branched_from] [hash before commit]
Затем в интерактивном ребазе вы просто добавляете правку в этот коммит. Когда дело доходит до сделать git commit --amend
и измените сообщение фиксации. Если вы хотите откатиться до этой точки фиксации, вы также можете использовать git reflog
и просто удалите этот коммит. Тогда вы просто делаете git commit
снова.
Если вы используете графический интерфейс Git, вы можете изменить последний коммит, который не был добавлен:
Commit/Amend Last Commit
Я использую Git GUI, насколько могу, и это дает вам возможность изменить последний коммит:
Также, git rebase -i origin/master
Это хорошая мантра, которая всегда представляет вам коммиты, которые вы сделали на вершине мастера, и дает вам возможность изменить, удалить, изменить порядок или сквош. Не нужно сначала получать этот хеш.
Для тех, кто ищет графический интерфейс для Windows/Mac, чтобы помочь с редактированием старых сообщений (т.е. не только самого последнего сообщения), я бы порекомендовал SourceTree. Шаги, чтобы следовать ниже.
Для коммитов, которые еще не были переданы на удаленное устройство:
- Убедитесь, что вы зафиксировали или сохранили все текущие изменения (т. Е. На вкладке "Состояние файла" нет файлов) - иначе это не сработает.
- На вкладке "Журнал / История" щелкните правой кнопкой мыши запись с примыкающей линией на графике под коммитом, который вы хотите редактировать, и выберите "Перебазировать потомков в
интерактивно..." - Выберите целую строку для сообщения фиксации, которое вы хотите изменить (т.е. нажмите на столбец "Сообщение").
- Нажмите кнопку "Редактировать сообщение".
- Отредактируйте сообщение, как требуется, в появившемся диалоговом окне и нажмите кнопку ОК
- Повторите шаги 3-4, если есть другие сообщения фиксации, которые нужно изменить.
- Нажмите OK: начнется ребазинг. Если все хорошо, вывод закончится "Завершено успешно".
... или... для коммитов, которые уже были выдвинуты:
Следуйте инструкциям в этом ответе, которые похожи на приведенные выше, но требуют, чтобы из командной строки выполнялась дополнительная команда для принудительного нажатия на ветвь - прочитайте все это и примите необходимые меры предосторожности!
Вау, так что есть много способов сделать это.
Еще один способ сделать это - удалить последний коммит, но сохранить его изменения, чтобы вы не потеряли свою работу. Затем вы можете сделать еще один коммит с исправленным сообщением. Это будет выглядеть примерно так:
git reset --soft HEAD~1
git commit -m 'New and corrected commit message'
Я всегда делаю это, если я забываю добавить файл или внести изменения.
Не забудьте указать --soft
вместо --hard
иначе вы потеряете этот коммит целиком.
Если вы просто хотите отредактировать последний коммит, используйте:
git commit --amend
или же
git commit --amend -m 'one line message'
Но если вы хотите отредактировать несколько коммитов подряд, вам следует вместо этого использовать перебазирование:
git rebase -i <hash of one commit before the wrong commit>
В файле, подобном приведенному выше, напишите edit / e или одну из других опций и нажмите "сохранить" и выйти.
Теперь вы будете при первом неверном коммите. Внесите изменения в файлы, и они будут автоматически подготовлены для вас. Тип
git commit --amend
сохранить и выйти и введите
git rebase --continue
перейти к следующему выбору, пока не закончите со всеми вашими выборами.
Обратите внимание, что эти вещи изменяют все ваши хэши SHA после этой конкретной фиксации.
Если вы хотите изменить только ваше последнее сообщение, вы должны использовать --only
флаг или его ярлык -o
с commit --amend
:
git commit --amend -o -m "New commit message"
Это гарантирует, что вы случайно не улучшите свой коммит с помощью инсценировки. Конечно, лучше иметь правильное $EDITOR
конфигурации. Тогда вы можете оставить -m
опцию out, и git предварительно заполнит сообщение коммита старым. Таким образом, это может быть легко отредактировано.
Обновите ваше последнее сообщение о неверной фиксации новым сообщением о фиксации в одной строке:
git commit --amend -m "your new commit message"
Или попробуйте git reset, как показано ниже:
# You can reset your head to n number of commit
# NOT a good idea for changing last commit message
# but you can get an idea to split commit into multiple commits
git reset --soft HEAD^
# it will reset you last commit. Now, you
# can re-commit it with new commit message.
Использование сброса для разделения коммитов на меньшие коммиты
git reset
может помочь вам разбить один коммит на несколько коммитов:
# reset your head. I am resetting to last commits:
git reset --soft HEAD^
# (you can reset multiple commit by doing HEAD~2(no. of commits)
# Now, reset your head for splitting it to multiple commits
git reset HEAD
# add and commit your files seperately to make multiple commits: e.g
git add app/
git commit -m "add all files in app directory"
git add config/
git commit -m "add all files in config directory"
Здесь вы успешно разбили свой последний коммит на два коммита.
На этот вопрос есть много ответов, но ни один из них не объясняет в мельчайших подробностях, как изменить старые сообщения коммита, используя VIM. Я застрял, пытаясь сделать это сам, поэтому здесь я подробно опишу, как я это сделал, особенно для людей, которые не имеют опыта работы с VIM!
Я хотел изменить мои пять последних коммитов, которые я уже отправил на сервер. Это довольно "опасно", потому что, если кто-то уже извлек из этого, вы можете испортить ситуацию, изменив сообщения фиксации. Однако, когда вы работаете над своей маленькой веткой и уверены, что никто не потянул ее, вы можете изменить ее следующим образом:
Допустим, вы хотите изменить свои пять последних коммитов, а затем введите это в терминале:
git rebase -i HEAD~5
* Где 5 - количество сообщений коммита, которые вы хотите изменить. (поэтому, если вы хотите изменить 10-й на последний коммит, введите 10)
Эта команда введет вас в VIM, где вы сможете "редактировать" историю коммитов. Вы увидите свои последние 5 коммитов наверху, как это:
pick <commit hash> commit message
Вместо pick
тебе нужно написать reword
, Вы можете сделать это в VIM, набрав в i
, что заставляет вас перейти в режим INSERT. (Вы видите, что находитесь в режиме вставки по слову INSERT внизу) Для коммитов, которые вы хотите изменить, введите reword
вместо pick
Затем вам нужно сохранить этот экран и выйти из него. Для этого сначала перейдите в "командный режим", нажав кнопку esc. (вы можете проверить, что находитесь в командном режиме, если слово INSERT внизу исчезло) Затем вы можете ввести команду, набрав :
Команда сохранить и выйти wq
, Так что если вы введете :wq
ты на правильном пути.
Затем VIM проверит каждое сообщение коммита, которое вы хотите перефразировать, здесь вы можете изменить сообщения коммита. Вы сделаете это, войдя в режим INSERT, изменив сообщение фиксации, войдя в командный режим, сохраните и выйдите. Сделайте это 5 раз, и вы вне VIM!
Затем, если вы уже выдвинули свои неправильные коммиты, вам нужно git push --force
переписать их. Помни что git push --force
это довольно опасная вещь, поэтому убедитесь, что никто не вытащил сервер, поскольку вы выдвинули неверные коммиты!
Теперь вы изменили свои сообщения коммитов!
(Как вы видите, я не настолько опытен в VIM, поэтому, если я использовал неправильный "жаргон", чтобы объяснить, что происходит, не стесняйтесь меня поправлять!)
Вы можете использовать git-rebase-reword
Он предназначен для редактирования любого коммита (не только последнего) так же, как commit --amend
$ git rebase-reword <commit-or-refname>
Он назван в честь действия по перебазированию в интерактивном режиме для изменения коммита: "reword". Посмотрите этот пост и раздел интерактивного режима
Примеры:
$ git rebase-reword b68f560
$ git rebase-reword HEAD^
Я добавил псевдоним reci
, recm
за recommit (amend)
это, теперь я могу сделать это с git recm
или же git recm -m
,
$ vim ~/.gitconfig
[alias]
......
cm = commit
reci = commit --amend
recm = commit --amend
......
Я понял, что вставил коммит с опечаткой. Чтобы отменить, я сделал следующее:
git commit --amend -m "T-1000, advanced prototype"
git push --force
Предупреждение: принудительное нажатие ваших изменений перезапишет удаленную ветку вашей локальной. Убедитесь, что вы не собираетесь перезаписывать то, что хотите сохранить. Также будьте осторожны с принудительным нажатием измененного (переписанного) коммита, если кто-то еще поделится с вами веткой, потому что им нужно будет переписать свою собственную историю, если у них будет старая копия коммита, которую вы только что переписали.
Мне нравится использовать следующее:
git status
git add --all
git commit -am "message goes here about the change"
git pull <origin master>
git push <origin master>
Если вы не отправили код в удаленную ветку ( GitHub/ Bitbucket), вы можете изменить сообщение коммита в командной строке, как показано ниже.
git commit --amend -m "Your new message"
Если вы работаете над определенной веткой, сделайте это:
git commit --amend -m "BRANCH-NAME: new message"
Если вы уже нажали код с неправильным сообщением, и вам нужно быть осторожным при изменении сообщения. То есть, после того, как вы измените сообщение коммита и попробуете нажать его снова, у вас возникнут проблемы. Чтобы сделать это гладко, выполните следующие действия.
Пожалуйста, прочитайте весь мой ответ, прежде чем делать это.
git commit --amend -m "BRANCH-NAME : your new message"
git push -f origin BRANCH-NAME # Not a best practice. Read below why?
Важное примечание: при непосредственном использовании принудительного нажатия вы можете столкнуться с проблемами кода, которые другие разработчики работают в той же ветке. Поэтому, чтобы избежать этих конфликтов, вам нужно извлечь код из вашей ветки, прежде чем делать принудительное нажатие:
git commit --amend -m "BRANCH-NAME : your new message"
git pull origin BRANCH-NAME
git push -f origin BRANCH-NAME
Это лучший метод при изменении сообщения фиксации, если оно уже было отправлено.