Редагувати кореневу комісію в Git?


328

Існують способи змінити повідомлення з пізніших зобов’язань:

git commit --amend                    # for the most recent commit
git rebase --interactive master~2     # but requires *parent*

Як ви можете змінити повідомлення про фіксацію першої комісії (у якої немає батьків)?


Дивіться також stackoverflow.com/questions/11987914 / ...
fork0

Зокрема: використання змінної середовища GIT_COMMIT у сценаріїgit filter-branch --msg-filter
fork0

1
Дивись також stackoverflow.com/a/2309391/264607
BlackICE

Відповіді:


285

Припускаючи, що у вас чисте робоче дерево, ви можете зробити наступне.

# checkout the root commit
git checkout <sha1-of-root>

# amend the commit
git commit --amend

# rebase all the other commits in master onto the amended root
git rebase --onto HEAD HEAD master

23
Я вважаю, що це має бути git rebase --onto HEAD <sha1-of-root> master.
Андрій

5
Правильно, але ви хочете, щоб оригінальний кореневий фіксатор для <upstream> of git rebase. git rebaseзастосовує коміти в <branch> ( master), які не знаходяться в <upstream>; HEADне входить master, тому ваша версія намагається застосувати всі master.
Андрій

7
Так, переконайтеся, що це git rebase --onto HEAD <sha1-of-root>господар, де <sha1-of-root>той самий використовується git checkout <sha1-of-root>. Інакше у вас буде 2 first commit.
Енді

2
@Cupcake: Ви перевірили стару версію команди? Це має добре працювати. Поправка змінює повідомлення про фіксацію лише тому старий і новий кореневі зобов’язання вносять точно ті самі зміни, щоб старі кореневі фіксації пропускалися автоматично. Другий HEADгарантує , що всі коммітов розглядаються і що ми можемо використовувати версію два параметра перебазуватися , щоб повернутися на господаря. Зауважте, що ця відповідь передує існуванню --rootможливості перезавантажити.
CB Bailey

9
Відповідь ecdpalma нижче є набагато простішою та простішою та має більше голосів, прокручуйте людей!
Flimm

567

Станом на Git версії 1.7.12 , тепер ви можете використовувати

git rebase -i --root

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


2
чи можливо перезавантажити корінь усіх гілок за допомогою цієї команди? Схоже, це від'єднає поточну гілку до нового кореня, а всі інші гілки залишаться на старому корені
woojoo666

@ woojoo666, тоді вам доведеться переставити гілки на новий корінь. як завжди.
berkus

@Atcold це не працює, якщо немає кореня вище за течією
Кай

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

2
@Leo, що означає ваш коментар? Я не бачу зв’язку між першою частиною та другою - що стосується певного часу?
хлопчик

66

Щоб розширити відповідь ecdpalma , тепер ви можете скористатися --rootопцією, щоб сказати, rebaseщо ви хочете переписати корінь / першу команду:

git rebase --interactive --root

Тоді коренева фіксація відобразиться у списку TODO ребазування, і ви можете вибрати її для редагування чи переформулювання:

reword <root commit sha> <original message>
pick <other commit sha> <message>
...

Це пояснення --rootз документів Git rebase (міна акцентів):

Перезавантажте всі об'єкти, доступні з яких <branch>, замість обмеження їх <upstream>. Це дозволяє перезавантажити кореневі комікси на гілці .


12

Просто, щоб надати альтернативу більш високо оціненим відповідям:

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

git commit --allow-empty -m "Initial commit"

і тільки після цього починайте робити "справжні" зобов'язання. Тоді ви можете легко перезавантажити поверх того, що виконувати, наприклад, стандартним способомgit rebase -i HEAD^


4
Чи це не означає, що для того, щоб це працювало, вам потрібно мати передбачуваність (або бути психічним), щоб зробити пусту фіксацію право на самому початку свого проекту ? Мені це здається надзвичайно ситуативним , і взагалі не практичним . Як ти гадаєш? Що станеться, якщо я вже зробив 100 комісій, і мені раптом потрібно відредагувати кореневу комітку. Чи буде це все-таки спрацювати, у такому випадку, якщо я не зробив це порожнє зобов’язання на початку?

2
Редагування повідомлення кореневої фіксації - це, мабуть, не те, що ви зробили б після 100-ти. Іноді мені здається, що я просто хочу зробити gpo repo, роблячи певні кошики, знаючи, що як тільки я досягну певного зручного стану, я розіб'ю їх, наприклад, і переформулюю повідомлення. У будь-якому випадку, я передумав, і думаю, що абсолютно корисною справою для першої фіксації було б розміщення .gitattributesфайлу, а не пуста фіксація.
jakub.g

4

Ви можете використовувати git filter-branch:

cd test
git init

touch initial
git add -A
git commit -m "Initial commit"

touch a
git add -A
git commit -m "a"

touch b
git add -A
git commit -m "b"

git log

-->
8e6b49e... b
945e92a... a
72fc158... Initial commit

git filter-branch --msg-filter \
"sed \"s|^Initial commit|New initial commit|g\"" -- --all

git log
-->
c5988ea... b
e0331fd... a
51995f1... New initial commit

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