Як змінити існуючі, незапущені повідомлення про фіксацію?


7664

Я написав неправильну річ у повідомленні про вчинення.

Як я можу змінити повідомлення? Комісія ще не була висунута.


868
Для тих, хто щось нове, але важливий пункт Лорі про те, що ще не натиснув. Як і релізинг, це змінює історію. Якщо хтось клонував / витягнув з вашої репо-версії між оригінальною та переписаною історією, він не зможе витягнути після переписання (для цієї гілки).
Пат Нотц

Відповіді:


16124

Змінення останнього повідомлення про фіксацію

git commit --amend

відкриє ваш редактор, що дозволить вам змінити повідомлення про фіксацію останньої комісії. Крім того, ви можете встановити повідомлення про фіксацію безпосередньо в командному рядку за допомогою:

git commit --amend -m "New commit message"

... однак це може зробити багаторядкові повідомлення про введення або невеликі виправлення більш громіздкими для введення.

Переконайтеся , що у вас немає яких - або змін в оборотному копії поставив перед цим або вони отримають вчинені теж. ( Нестандартні зміни не будуть здійснені.)

Зміна повідомлення про зобов’язання, яке ви вже перенесли на віддалений відділення

Якщо ви вже підштовхнули свою комісію до віддаленої гілки, то - після внесення змін до місцевого комітету (як описано вище) - вам також потрібно буде змусити натиснути комісію за допомогою:

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

Попередження: натискання силою замінить віддалену гілку зі станом вашого локального . Якщо є фіксації на віддаленому філії , що ви не маєте в вашому місцевому відділенні, ви будете втрачати ці коммітов.

Попередження: будьте обережні щодо внесення змін до зобов’язань, якими ви вже поділилися з іншими людьми. Зміни комісій по суті переписують їх на різні ідентифікатори SHA , що створює проблему, якщо інші люди мають копії старої комісії, яку ви переписали. Кожен, хто має копію старої фіксації, повинен синхронізувати свою роботу з вашим нещодавно переписаним комітетом, що іноді може бути важким, тому обов'язково координуйтеся з іншими при спробі переписати спільну історію фіксації або просто уникайте перезапису спільних комісій. взагалі.


Виконайте інтерактивну базу даних

Інший варіант - використовувати інтерактивну базу даних. Це дозволяє редагувати будь-яке повідомлення, яке ви хочете оновити, навіть якщо це не останнє повідомлення.

Для того, щоб зробити сквот Git, виконайте наступні дії:

// n is the number of commits up to the last commit you want to be able to edit
git rebase -i HEAD~n

Після того, як ви скорочуєте свої зобов’язання - виберіть e/rдля редагування повідомлення:

Введіть тут опис зображення

Важлива примітка про інтерактивну базу даних

При використанні git rebase -i HEAD~nїх може бути більше n комісій. Git буде "збирати" всі коміти в останніх n комісіях, і якщо відбулося злиття десь між цим діапазоном, ви також побачите всі коміти, тож результат буде n +.

Гарна порада:

Якщо вам доведеться це робити для більше ніж однієї гілки, і ви можете зіткнутися з конфліктами під час внесення змін до вмісту, налаштуйте git rerereта дозвольте Git автоматично вирішувати ці конфлікти за вас.


Документація


257
Однак git commit --amendхіба не такий потужний, як git rebase -i.
Джефрі Хосе

76
@jeffjose, Це точно не потрібно. Також git commit --amendможна зафіксувати (a?) Головний коміт.
страгер

116
Якщо ви вже штовхнули, просто натисніть знову:git push -f origin branchname
обіймає

177
@hughes не git push -fє дещо небезпечним, якщо інші люди використовують те саме сховище?
Арман

91
Якщо ви не хочете переписати все повідомлення про фіксацію, перейдіть git commit --amend -c HEAD. Це відкриє редактор, попередньо заповнений вашим старим повідомленням фіксації, так що ви можете змінити його.
Сем

2506
git commit --amend -m "your new message"

7
Я зробив git набір --amend -m "Нове повідомлення", але натискання на Github породило "Об'єднати віддалені зміни, перш ніж натиснути знову". Після витягування, виконайте --менюйте і натисніть знову, нове повідомлення не з’являється. Натомість у мене є "Об'єднати гілку" майстер "з github.com: evidencemyrepo]"
Дейв Еверітт

8
@DaveEveritt ви, швидше за все, підштовхнули свої зобов'язання вгору, перш ніж спробувати виправити це.
Thorbjørn Ravn Andersen

12
@Kyralessa неправда. У bash ви можете легко скласти багаторядкові повідомлення про фіксацію, просто не закриваючи цитату, поки не закінчите (натискаючи на повернення в кінці кожного рядка в лапках).
варильні панелі

32
Я не розумію, як відповідь, що дуже схожа на головну думку відповіді, написану два роки тому, а також прийнята відповідь отримує стільки голосів. Дивно. (нічого поганого у відповіді, хоча)
щасливий кодер

7
@AmalMurali, добре. Моя думка полягала не стільки в популярності питання, ні корисності відповіді. Але ця конкретна відповідь не є найдавнішою відповіддю, і не дає подальшого розуміння прийнятої відповіді. Схоже, це копія розділу прийнятої відповіді. Це був мій погляд. ВЕЛИКИ!
щасливий кодер

2376

Якщо комісія, яку ви хочете виправити, не є останньою:

  1. git rebase --interactive $parent_of_flawed_commit

    Якщо ви хочете виправити кілька недолікових комісій, передайте батьків найстарішого з них.

  2. З'явиться редактор із переліком усіх комісій з тих, що ви надали.

    1. Перейдіть pickна reword(або на старі версії Git, на edit) перед будь-якими комісіями, які ви хочете виправити.
    2. Після збереження Git відтворює перелічені комітети.

  3. Щоразу, коли ви хочете змінити слово , Git поверне вас до свого редактора. За кожне зобов’язання, яке ви хочете відредагувати , Git скидає вас у оболонку. Якщо ви в оболонці:

    1. Змініть комісію будь-яким способом, який вам подобається.
    2. git commit --amend
    3. git rebase --continue

Більшість цієї послідовності буде пояснено вам результатами різних команд під час руху. Це дуже просто; вам не потрібно запам'ятовувати це - просто пам’ятайте, що git rebase --interactiveдозволяє виправляти вчинки незалежно від того, як давно вони були.


Зауважте, що ви не хочете змінювати коміти, які ви вже натиснули. Або, можливо, ви так робите, але в такому випадку вам доведеться дуже обережно спілкуватися з усіма, хто, можливо, взяв на себе ваші зобов’язання та зробив роботу над ними. Як відновити / відновити синхронізацію після того, як хтось натисне ребазу чи скидання до опублікованої гілки?


39
Чи можна змінити повідомлення першого комітету (у якого немає батьків)?
13рен

27
Про це йдеться в одній з інших відповідей, але я зазначу це тут. Оскільки git 1.6.6 ви можете використовувати rewordзамість pickредагування повідомлення журналу.
MitMaro

89
До речі, $parent_of_flawed_commitрівнозначно $flawed_commit^.
Peeja

67
Ніколи НЕ РОБИТИ цього (або взагалі перезавантаження), якщо ви вже просунулися вгору за течією!
Даніель Рінсер

20
Використовуйте -p( --preserve-merges), якщо відбулося злиття після несправної фіксації.
ахвен

778

Щоб внести зміни до попереднього зобов’язання, зробіть потрібні зміни та сформулюйте ці зміни та запустіть

git commit --amend

Це відкриє файл у вашому текстовому редакторі, що представляє ваше нове повідомлення про фіксацію. Він починається із заповнення тексту зі старого повідомлення про фіксацію. Змініть повідомлення про фіксацію за своїм бажанням, а потім збережіть файл та закрийте редактор, щоб закінчити.

Щоб змінити попередню комісію та зберегти те саме повідомлення журналу, запустіть

git commit --amend -C HEAD

Щоб виправити попередній комітет, видаливши його повністю, запустіть

git reset --hard HEAD^

Якщо ви хочете відредагувати більше одного повідомлення про фіксацію, запустіть

git rebase -i HEAD~commit_count

(Замініть команду_облік на кількість комісій, які ви хочете відредагувати.) Ця команда запускає ваш редактор. Позначте першу комісію (ту, яку ви хочете змінити) як "редагувати" замість "вибору", а потім збережіть і вийдіть із редактора. Зробіть зміни, які ви хочете зробити, а потім запустіть

git commit --amend
git rebase --continue

Примітка. Ви також можете "Зробити потрібні зміни" в редакторі, відкритому користувачем git commit --amend


18
git rebase -i HEAD~commit_countтакож дозволить вам змінювати повідомлення про фіксацію, скільки завгодно вибраних вами зобов’язань. Просто позначте вибрані доручення як "reword", а не "pick".
Джо

2
Що робити, якщо ви не хочете проводити перезавантаження? Ви просто хочете змінити старе повідомлення?
SuperUberDuper

3
git reset --hardзнищує неспроможні зміни. Будь ласка, замініть --hardна --soft.
вугор ghEEz

1
Погоджено, git reset --hardце цілком законна команда, але вона вводить в оману з огляду на питання. Ви використовуєте, --hardякщо ви здійснили зміни, які хочете викинути, а не якщо ви зробили помилковий друк у повідомленні про вчинення!
Сорен Бьорнстад

398

Як уже згадувалося, git commit --amendце спосіб перезаписати останню команду. Одне зауваження: якщо ви хочете також перезаписати файли , команда буде

git commit -a --amend -m "My new commit message"

4
І якщо ви не хочете додавати все, спочатку можете зробити це git add file.extпростоgit commit --amend
MalcolmOcean

358

Ви також можете використовувати git filter-branchдля цього.

git filter-branch -f --msg-filter "sed 's/errror/error/'" $flawed_commit..HEAD

Це не так просто, як тривіальне git commit --amend, але особливо корисно, якщо у вас вже є кілька злиття після вашого помилкового повідомлення про фіксацію.

Зауважте, що це спробує переписати кожну комісію між HEADта недосконалою комісією, тому вам слід msg-filterдуже обережно вибрати команду ;-)


4
Чи є версія цієї версії, яка не змінює комісію, якщо регулярний вираз не знайде нічого?
sjakubowski

3
AFAIK фільтр-гілка --msg-filter створить нові коміти в будь-якому випадку. Однак ви можете перевірити в msg-filter, чи вдався sed і використати цю інформацію, коли операція гілки фільтра закінчиться, щоб скинути дерево на refs / original.
Марк

4
@DavidHogue Це справедливо лише під час використання методу гілки фільтрів. Ідентифікатори комісій після модифікованої комісії не змінюються, якщо ви використовуєте інтерактивну базу даних.
Марк

6
@ Марк Так, вони це вимагають. Ідентифікатори комісій залежать від попередніх комісій. Якби вони не змінилися, git був би марним.
Майлз Рут

2
Вам потрібно $flawed_commit^..HEAD, ні $flawed_commit..HEAD. як зазначено на сторінці man: « Команда перепише лише позитивні рефлекси, згадані в командному рядку (наприклад, якщо ви передасте a..b, буде переписано лише b). »
Ángel

319

Я віддаю перевагу таким чином:

git commit --amend -c <commit ID>

В іншому випадку буде новий комітет з новим посвідченням комісії.


7
Для мене, використовуючи вашу команду вище, фактично створюється нова комісія з новим ідентифікатором комісії плюс додаткова фіксація, що говорить "об'єднати гілку" як повідомлення про фіксацію за замовчуванням.
Jan

46
Зміни завжди створюють нову комісію з новим ідентифікатором комісії. Ідентифікатор фіксації - це хеш-вміст SHA вмісту комісії, включаючи повідомлення про фіксацію та авторські / скоєні часові позначки. Це особливість Git, яка, забороняючи хеш-зіткнення, забезпечує те, що два коміти з однаковим ідентифікатором є точно однаковими фіксаціями, з точно однаковим вмістом, історією тощо.
Еміль Лундберг

7
Погодьтеся з Емілем. Крім того, читаючи документи - схоже, що все "-c" - це сказати git, яке повідомлення комісії використовувати як за замовчуванням / шаблон для вашого нового комітету. Дійсно, це вже буде робити "-c <ідентифікатор ID>" за замовчуванням , тому не потрібно її вказувати.
Гал

2
-cРобить кілька речей. За умовчанням воно використовує старе повідомлення, але також копіює інформацію про авторство (особу та час). -Cробить те саме, за винятком того, що він не просить вас редагувати повідомлення.
Джозеф К. Стросс

1
Як і @SantanuDey, це не працювало для мене. Я отримавfatal: Option -m cannot be combined with -c/-C/-F/--fixup.
Ендрю Грімм

312

Якщо ви використовуєте інструмент Git GUI, є кнопка під назвою Змінити останню фіксацію . Натисніть на цю кнопку, і тоді вона відобразить ваші останні файли фіксування та повідомлення. Просто відредагуйте це повідомлення, і ви можете скористатись новим повідомленням про фіксацію.

Або скористайтеся цією командою з консолі / терміналу:

git commit -a --amend -m "My new commit message"

4
Ця відповідь буквально ідентична цій старшій . Ви перевірили наявні відповіді, перш ніж надсилати ще одну?
Дан Даскалеску

284

Можна використовувати ритм Git . Наприклад, якщо ви хочете змінити назад, щоб зробити bbc643cd, запустіть

$ git rebase bbc643cd^ --interactive

У редакторі за замовчуванням змініть "pick" на "редагувати" у рядку, чиє зобов'язання ви хочете змінити. Внесіть зміни, а потім сформулюйте їх

$ git add <filepattern>

Тепер ви можете використовувати

$ git commit --amend

щоб змінити комісію, і після цього

$ git rebase --continue

щоб повернутися до попереднього головного комітету.


1
Якщо ви хочете переконатися, що ваша зміна на зміну git commit --amendвплинула, ви можете використовувати git showїї, і на ній з’явиться нове повідомлення.
Стів Таубер

279
  1. Якщо ви хочете лише змінити останнє повідомлення про фіксацію, виконайте такі дії:

    git commit --amend
    

Це введе вас у ваш текстовий редактор і дозволить вам змінити останнє повідомлення про фіксацію.

  1. Якщо ви хочете змінити останні три повідомлення фіксації, або будь-який з повідомлення фіксації до цього моменту, поставки HEAD~3в git rebase -iкоманді:

    git rebase -i HEAD~3
    

6
Це раніше відповідь вже говорить про те, що ви можете використовувати git commit --amend, і він також говорить , що ви можете використовувати git rebase -i HEAD~commit_countвсі , що ви зробили в плагін 3для commit_count.

Неприхильні також. Люди просто не намагаються читати наявні відповіді .
Дан Даскалеску

261

Якщо вам доведеться змінити старе повідомлення про фіксацію в декількох гілках (тобто фіксація з помилковим повідомленням присутня в декількох гілках), ви можете скористатися:

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

3
Ця відповідь не стосується питання ОП, оскільки вони суто зацікавлені у фіксації зобов'язань, які вони тільки що зробили. Я регулярно використовую git commit --amendдля виправлення коментарів або додавання файлів, про які я забув git add, але лише раніше, ніж я git pushредагував. Я також використовую, git filter-branchколи я хочу повністю заплутатися з історією версій, але ОП не хоче цього, тому ця відповідь потребує великого попередження про здоров'я - не намагайтеся цього вдома, заглядає !!
кбро

226

Використовуйте

git commit --amend

Щоб його детально зрозуміти, чудовий пост - 4. Переписування історії Git . Це також говорить про те, коли не використовувати git commit --amend .


2
Чи є хороший спосіб виправити повідомлення про фіксацію, вже переміщені до загальнодоступного сховища? Поки я прийшов до висновку, що, як тільки натиснув, мої повідомлення про вчинення помилок та тонкості повинні жити вічно.
стік потоку

2
Одним словом, НАДЕ! Немає ДОБРЕ способу відкрутити те, що ти штовхнув. Всі втягування БАД у більшій чи меншій мірі. Потрібно засвоїти дисципліну роботи у філії у власному приватному сховищі, виконуючи кілька комісій, коли ви додаєте трохи, тестуєте трохи, перетворюєте трохи. Потім об’єднайте всю свою гілку в одну комісію, напишіть нове повідомлення про фіксацію, що описує загальну зміну, ПРОФОНУЙТЕ її та натисніть.
кбро

1
Просто для того, щоб вказати на очевидне, що не потрібно робити жодного зобов’язання, повертаючись із гілки функції. Те, що багато хто робить, - це перекомпонування на цільовій гілці (щоб все виглядало чисто), а потім злиття з можливістю придушити швидку перемотку. Погодьтеся з головним моментом бути обережними, перш ніж натиснути.
ShawnFumo

1
git commit --amendВідповідь вже була дана ( в кілька разів) , перш ніж ви написали ваші. Чому ви опублікували це знову? Якщо ви хочете додати посилання на "Перезапис історії Git", ви могли відредагувати одну з існуючих відповідей або залишити коментар.
Дан Даскалеску

199

Поправити

Тут у вас є пара варіантів. Ви можете зробити

git commit --amend

до тих пір, поки це ваше останнє зобов'язання.

Інтерактивна база даних

В іншому випадку, якщо це не ваша остання фіксація, ви можете зробити інтерактивну базу даних,

git rebase -i [branched_from] [hash before commit]

Тоді всередині інтерактивної бази ви просто додаєте редагування до цього файлу. Коли воно з'являється, зробіть git commit --amendі змініть повідомлення про фіксацію. Якщо ви хочете відкотитись перед цим пунктом фіксації, ви можете також скористатися git reflogі просто видалити це. Тоді ти git commitзнову робиш знову.


191

Якщо це ваше останнє зобов'язання, просто внесіть зміни :

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 клавіш 3jcwrEscZZ):

  • Бігайте, vimtutorякщо у вас є час
  • hjkl відповідають клавішам руху
  • Усі команди можуть бути префіксованими "діапазоном", наприклад, 3jрухається вниз по трьох рядках
  • i для переходу в режим вставки - текст, який ви вводите, з’явиться у файлі
  • Escабо Ctrlcвийти з режиму вставки та повернутися до «нормального» режиму
  • u скасувати
  • Ctrlr переробити
  • dd, dw, dlЩоб видалити рядок, слово або букву, відповідно
  • cc, cw, clЩоб змінити рядок, слово або букву, відповідно ( так само , як ddi)
  • yy, yw, ylКопіювати ( «смикнув») лінію, слово або букву, відповідно
  • pабо Pвставити відповідно після або перед поточним положенням відповідно
  • :wEnter зберегти (записати) файл
  • :q!Enter кинути без економії
  • :wqEnterабо ZZзберегти і кинути

Якщо ви багато редагуєте текст, перейдіть на розкладку клавіатури Dvorak , навчіться набирати сенсорний тип та вивчити Vim. Чи варто докладати зусиль? Так.



ProTip ™: не бійтеся експериментувати з "небезпечними" командами, які переписують історію * - Git не видаляє ваші зобов'язання протягом 90 днів за замовчуванням; ви можете знайти їх у рефлозі:

$ git reset @~3   # Go back three 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хоча - вони можуть відкинути дані. * Також не переписуйте історію на жодних гілках, над якими ви співпрацюєте.


3
Частина vim - це абсолютно поза темою, і замість того, щоб заохочувати користувачів витрачати час на навчання, використовуючи таємний редактор, чому б не навчити їх чомусь більш тематичному, наприклад, як налаштувати редактор git за замовчуванням, щоб це було щось зручне для користувачів, наприклад nano? Ми говоримо про тривіальні модифікації, які потрібно вносити в текстовий файл, а не на жорстке кодування, яке породжувало б вогняну війну щодо «найкращого» редактора тексту.
Дан Даскалеску

1
@DanDascalescu: Тому що швидше навчитися Vim, використовуючи наведені вище інструкції, ніж виконувати кілька повторних баз за допомогою нано. Ціла причина, що git відкриває текстовий редактор, а не власний інтерфейс для повторної публікації - це те, що Vim існує: він легкий, встановлений за замовчуванням у більшості систем і дуже простий у навчанні, достатньо легко виконувати ребауз: наприклад, ddjjpZZрухає команду 2 вниз. Немає нічого загадкового в базових знаннях Vim; знадобиться 10 хвилин, щоб з Vim стало комфортніше, ніж нано.
Заз

185

Якщо ви використовуєте графічний інтерфейс Git, ви можете внести зміни до останнього комітету, на який не було натискано:

Commit/Amend Last Commit

168

Я максимально використовую графічний інтерфейс Git , і це дає вам можливість вносити зміни до останнього комітету:

Поставте прапорець у цьому полі

Крім того, git rebase -i origin/masterце приємна мантра, яка завжди буде представляти вам зобов’язання, які ви зробили поверх майстра, і дасть вам можливість вносити зміни, видалення, переупорядкування або скрінш. Не потрібно спочатку захоплюватися цим хешем.


4
Як я можу потрапити на той екран, який ви показали у своєму прикладі?
Marwan مروان

2
Це нижня права частина Windows Git Gui. Просто виберіть перемикач "Змінити останнє зобов'язання", і він заповниться найсвіжішою інформацією про фіксацію.
wbdarby

138

Нічого собі, тому існує маса способів зробити це.

Ще один спосіб зробити це - видалити останню комісію, але збережіть її зміни, щоб ви не втратили роботу. Потім ви можете зробити ще одну фіксацію з виправленим повідомленням. Це виглядатиме приблизно так:

git reset --soft HEAD~1
git commit -m 'New and corrected commit message'

Я завжди роблю це, якщо забуду додати файл або внести зміни.

Не забудьте вказати --softзамість --hard, інакше ви повністю втратите ці зобов'язання.


5
Це робить саме те саме, що, git commit --amendза винятком того, що це двоетапний процес.
Джозеф К. Стросс

3
@ JosephK.Strauss Я вважаю, що зміна комісії також зберігає оригінальну інформацію про автора та дату, маючи окрему інформацію про нове виконувачу та дату. Я не впевнений, що такий підхід робить це.
Евертон

4
@EvertonAgner Ви маєте рацію. --amendзбереже інформацію про автора, але питання запитує лише змінити повідомлення.
Джозеф К. Стросс

131

Для всіх, хто шукає графічний інтерфейс Windows / Mac, щоб допомогти в редагуванні старих повідомлень (тобто не тільки останнього повідомлення), я рекомендую Sourcetree . Нижче описані кроки.

Інтерактивна база даних Sourcetree

Для комітетів, які ще не були висунуті на пульт:

  1. Переконайтеся, що ви здійснили або приховали всі поточні зміни (тобто, щоб не було файлів, перелічених на вкладці "Стан файлу") - це не буде працювати інакше.
  2. На вкладці "Журнал / Історія" клацніть правою кнопкою миші на запис із суміжним рядком у графі один під коміт (ими), який ви бажаєте відредагувати, та виберіть "Інтерактивне відновлення дітей <<ref ref>> ..."
  3. Виберіть весь рядок для повідомлення про фіксацію, яке ви хочете змінити (натисніть на стовпчик "Повідомлення") .
  4. Натисніть кнопку "Редагувати повідомлення".
  5. Відредагуйте повідомлення за бажанням у діалоговому вікні, що з’явиться, а потім натисніть кнопку OK.
  6. Повторіть кроки 3-4, якщо є інші повідомлення про фіксацію.
  7. Клацніть OK: Почнеться звільнення. Якщо все добре, вихід закінчиться "Завершено успішно". ПРИМІТКА. Іноді я бачив цю помилку Unable to create 'project_path/.git/index.lock': File exists.при спробі змінити кілька повідомлень про фіксацію одночасно. Не точно знаєте, у чому полягає проблема, чи буде вона виправлена ​​в майбутній версії Sourcetree, але якщо це станеться, рекомендую їх повторно опускати (повільніше, але здається більш надійним).

... Або ... для комітетів, які вже були натиснуті:

Виконайте кроки в цій відповіді , які схожі на вище, але вимагають виконання наступної команди з командного рядка ( git push origin <branch> -f) для примусового натискання гілки. Я рекомендую прочитати все це і дотримуватися необхідної обережності!


з усіх відповідей - це найбільше підходить для всіх git newbies ^^^ (використовуйте безкоштовну програму SourceTree та застосуйте "Rebase children of" на комітеті перед тим, який ви хочете редагувати)
revelt

127

Якщо ви просто хочете відредагувати останню комісію, скористайтеся:

git commit --amend

або

git commit --amend -m 'one line message'

Але якщо ви хочете відредагувати кілька комісій підряд, замість цього слід скористатися перезаписом:

git rebase -i <hash of one commit before the wrong commit>

Редагування Git Rebase

У файл, як у наведеному вище, запишіть edit/eабо один із інших параметрів, натисніть зберегти та вийти.

Тепер ви будете на першому неправильному здійсненні. Внесіть зміни у файли, і вони будуть автоматично встановлені для вас. Тип

git commit --amend

Збережіть і вийдіть із цього і введіть

git rebase --continue

щоб перейти до наступного вибору до тих пір, поки не буде завершено всі ваші вибори.

Зауважте, що ці речі змінюють всі ваші хеші SHA після цього конкретного введення.


2
git rebase -i <хеш одного коміту перед неправильним фіксом> працює для мене. Дякую.
Вірат

127

Якщо ви хочете змінити лише своє останнє повідомлення, вам слід використовувати --onlyпрапор або його ярлик -oіз commit --amend:

git commit --amend -o -m "New commit message"

Це гарантує, що ви не випадково посилите свої зобов’язання поетапними речами. Звичайно, найкраще мати правильну $EDITORконфігурацію. Тоді ви можете залишити -mваріант, і Git попередньо заповнить повідомлення про фіксацію старим. Таким чином його можна легко редагувати.


1
Відповідь "верх" не відповідає на запитання. Це просто дає загальне вступ до git commit --amend. Питання було дуже конкретним, тому довше! = Краще. Вирішальна згадка -oпрапора, ймовірно, буде похована в решті інформації. Мені також не комфортно редагувати відповідь, в якій вже так багато голосів.
Девід Онгаро

2
Коли це сказано, ви вільні редагувати основну відповідь, оскільки існує реальна небезпека, що люди використовують це як "правильну" відповідь. Ви можете легко змінити свої зобов'язання з поетапними речами - це сталося зі мною, і це насправді дратує, коли вам трапляється це натиснути. Але все-таки кількість не є гарантією коректності. Ні за кількістю відповідей, ні за кількістю голосів.
Девід Онгаро

1
Я б не пішов так далеко, щоб сказати, що головна відповідь "невірна" і що "не відповідає на питання". Це, безумовно, працює і відповідає на питання, вам просто потрібно переконатися, що ви не зробили поетапних змін при спробі внесення змін. Але я бачу ваш пункт про те, що потрібно попередити людей про це. Я відредагую його згодом, якщо матиму час.

1
Справедливості: навіть якщо --onlyопція з --amendдоступна, оскільки git 1.3.0 не працює належним чином, поки вона не була зафіксована у 1.7.11.3 ( ea2d4ed35902ce15959965ab86d80527731a177c ). Таким чином, правильна відповідь ще в 2008 році, ймовірно, було що - щось на кшталт: git stash; git commit --amend; git stash pop.
Девід Онгаро

103

Оновіть своє останнє повідомлення про неправильну фіксацію новим повідомленням про фіксацію в одному рядку:

git commit --amend -m "your new commit message"

Або спробуйте скинути Git, як показано нижче:

# 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 separately 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"

Тут ви успішно розбили свій останній документ на два коміти.


3
Якщо все, що ви хочете зробити, - це відредагувати повідомлення останньої фіксації, використання м'якого скидання для цієї мети є надмірним вбивством . Просто використовуйте git commit --amend, точно так само як , як він каже , в верхній проголосували відповідь . Крім того, git reset --soft HEAD^в цьому попередньому відповіді працює ідентично м'якому скиданню , оскільки вони обидва скидаються до першого батьківського комітету.

3
Я лише намагаюся додати git resetдо рішення лише те, щоб дати ідею розділити одне повідомлення про фіксацію на кілька повідомлень про фіксацію. Тому що я зіткнувся з цією проблемою, коли я починав використовувати git. Іноді це може бути справді корисним. :)
przbadu

87

На це питання є багато відповідей, але жоден з них не пояснює дуже докладно, як змінити старі повідомлення про фіксацію за допомогою Vim . Я застряг у спробах зробити це сам, тому тут докладно напишу, як я це робив спеціально для людей, які не мають досвіду роботи у Vim!

Я хотів змінити свої п'ять останніх зобов’язань, які я вже натиснув на сервер. Це досить "небезпечно", оскільки якщо хтось із них уже вийшов із цього, ви можете зіпсувати речі, змінивши повідомлення про фіксацію. Однак, коли ви працюєте над власною маленькою гілкою і впевнені, що її ніхто не потягнув, ви можете змінити її так:

Скажімо, ви хочете змінити свої п'ять останніх комісій, а потім введіть це в терміналі:

git rebase -i HEAD~5

* Де 5 - кількість повідомлень про фіксацію, яку ви хочете змінити (тому, якщо ви хочете змінити 10-те на останнє виконання, введіть 10).

Ця команда переведе вас у Vim, там ви зможете "відредагувати" свою історію комісій. Угорі ви побачите свої останні п’ять комісій:

pick <commit hash> commit message

Замість цього pickпотрібно писати reword. Це можна зробити у Vim, ввівши текст i. Це змушує вас зайти в режим вставки . (Ви бачите, що ви перебуваєте у режимі вставки за допомогою слова INSERT внизу.) Для комісій, які ви хочете змінити, введіть rewordзамість pick.

Тоді вам потрібно зберегти та закрити цей екран. Виконайте це, спочатку перейшовши в «командний режим» натисканням Escкнопки (ви можете перевірити, чи перебуваєте ви в командному режимі, якщо слово INSERT внизу зникло). Потім ви можете ввести команду, ввівши :. Команда зберегти та вийти - це wq. Тож якщо ви введете, :wqви на правильному шляху.

Тоді Vim перегляне кожне повідомлення про фіксацію, яке потрібно переробити, і тут ви можете фактично змінити повідомлення про фіксацію. Ви зробите це, перейшовши в режим вставки, змінивши повідомлення про фіксацію, перейдіть в командний режим, а також збережіть і вийдіть. Зробіть це п’ять разів, і ви поза Вімом!

Потім, якщо ви вже підштовхнули свої помилкові зобов’язання, вам потрібно git push --forceїх перезаписати. Пам’ятайте, що git push --forceце досить небезпечно, тому переконайтеся, що ніхто не витягував з сервера, оскільки ви пересунули свої неправильні зобов’язання!

Тепер ви змінили свої повідомлення про фіксацію!

(Як бачите, я не такий досвід у Vim, тож якщо я використав неправильне "лінго", щоб пояснити, що відбувається, сміливо виправляйте мене!)


4
<nitpick>У Stack Overflow немає "потоків", оскільки це не дискусійний форум, є лише "питання", "відповіді" та "повідомлення". </nitpick>. Крім того, не всі версії Vim однакові, не всі вони дозволять видаляти символи в режимі вставки (має сенс певним чином, правда?). Якщо ви хочете завжди мати змогу видаляти символи у Vim, Xі xзробите це (трохи xвидаляє символи перед курсором, Xвидалить ззаду). Якщо ви робите помилки, ви можете uкілька разів використовувати їх для скасування. Нарешті, rце скорочення rewordв інтерактивному редакторі ребатів.

1
Щоб змінити слово в vim, cwнабирається на початку (хоча питання не про vim, я згоден).
Ярослав Нікітенко

Вам не потрібно використовувати цю гидоту . Ви можете встановити свій редактор git на щось здорове та зручне для користування, наприклад nano, mcedit Midnight Commander.
Дан Даскалеску

79

Ви можете використовувати git-rebase-reword

Він призначений для редагування будь-яких комісій (не тільки останніх) так само, як і commit --amend

$ git rebase-reword <commit-or-refname>

Він названий після дії на інтерактивну базу даних для внесення змін до комітету: "reword". Дивіться цю публікацію та людину - інтерактивний режим -

Приклади:

$ git rebase-reword b68f560
$ git rebase-reword HEAD^

6
Для цього потрібна установка зовнішньої програми. На мою думку, краще було б навчитися ефективніше використовувати вбудовані інструменти та псевдоніми. Я б набрав: g c; g rb -i @~9(виконувати і перезавантажувати), переміщувати нову комісію туди, де я хочу, змінити commitна f( fixup) та зберегти. Якщо ви хотіли чогось швидшого за це, можете створити псевдонім git commit --fixup=<commit>; git rebase -i --autosquash <commit>^
Заз

79

Я додав псевдоніми reciі recmдля recommit (amend)цього. Тепер я можу це зробити з git recmабо git recm -m:

$ vim ~/.gitconfig

[alias]

    ......
    cm = commit
    reci = commit --amend
    recm = commit --amend
    ......

57

Я зрозумів, що я підштовхнув команду з друкарською помилкою. Щоб скасувати, я зробив наступне:

git commit --amend -m "T-1000, advanced prototype"
git push --force

Попередження: примусові натискання змін замінять віддалену гілку з локальною. Переконайтеся, що ви не збираєтеся перезаписувати все, що хочете зберегти. Також будьте обережні щодо примусового натискання зміненої (переписаної) фіксації, якщо хтось ще поділиться з вами відділенням, тому що їм потрібно буде переписати власну історію, якщо у них є стара копія зобов’язання, яку ви тільки що переписали.


7
Ніколи нічого не перезаписується в git. У цьому випадку вказівник гілки буде встановлений у вашому новому фіксації, і стара фіксація застаріла, якщо на неї не залишиться жодних посилань, і вона може очиститися через кілька тижнів. (До цього часу інші все ще можуть знайти і посилатися на це, наприклад, заглянувши в рефлог.)
David Ongaro

51

Мені подобається використовувати наступне:

  1. git status
  2. git add --all
  3. git commit -am "message goes here about the change"
  4. git pull <origin master>
  5. git push <origin master>

46

Якщо ви не натиснули код на віддалену гілку ( 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

Це найкраща практика при зміні повідомлення про фіксацію, якщо воно вже було натиснуто.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.