Как перефразировать самое первое сообщение git commit?

117

У меня есть рабочее дерево, содержащее 3 коммита:

➜ ~ myproject git: (мастер) git log

commit a99cce8240495de29254b5df8745e41815db5a75
Author: My Name <my@mail.com>
Date:   Thu Aug 16 00:59:05 2012 +0200

    .gitignore edits

commit 5bccda674c7ca51e849741290530a0d48efd69e8
Author: My Name <my@mail.com>
Date:   Mon Aug 13 01:36:39 2012 +0200

    Create .gitignore file

commit 6707a66191c84ec6fbf148f8f1c3e8ac83453ae3
Author: My Name <my@mail.com>
Date:   Mon Aug 13 01:13:05 2012 +0200

    Initial commit (with a misleading message)

Теперь я хочу получить rewordсообщение о моей первой фиксации (6707a66)

➜ ~ myproject git: (мастер) git rebase -i 6707

(… Вход в vim)

pick 5bccda6 Create .gitignore file
pick a99cce8 .gitignore edits

# Rebase 6707a66..a99cce8 onto 6707a66
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

В этом случае я хочу исправить ( rewordна языке git) рассматриваемое сообщение фиксации:

Первоначальная фиксация (с вводящим в заблуждение сообщением)

… К чему-то подходящему.

Неудивительно, что моя попытка выше не увенчалась успехом, поскольку первая фиксация явно не имеет родительской фиксации. (И когда вам rebaseнужно ссылаться на следующую самую старую фиксацию до той, которую вы хотите reword, верно?)

Таким образом, суть моего вопроса: можете ли вы добиться этого другими способами?

Хенрик
источник
Или вы могли бы просто оставить это навсегда как безвкусную причуду
Кристофер
4
возможный дубликат Изменение сообщения первого коммита? (git)
Марк Лонгэр
^ Совершенно верно ... Я думал, что правильно искал этот конкретный вопрос, но это тот же самый, что и мой. Я проделал огромную работу по совершенствованию копирайтинга моего вопроса. :-P
Хенрик
1
@hced: :) ваш копирайтинг не пропадет даром - он поможет другим людям найти решение в будущем, даже если он будет закрыт как дубликат
Марк Лонгэр
2
Любой, кто сталкивается с этим вопросом, может найти мой ответ на изменение сообщения первой фиксации? (git), чтобы быть полезным.

Ответы:

216

Делать git rebase -i --root

(укажите rootвместо указания на конкретную фиксацию)

Таким образом, первая фиксация также включена, и вы можете использовать rewordее, как и любую другую фиксацию.

--rootВариант был введен в Git v1.7.12(2012). Раньше единственным вариантом было использовать filter-branchили --amend, что обычно труднее.

Примечание: см. Также этот аналогичный вопрос и ответ .

Флорисла
источник
12

Вы всегда можете использовать git filter-branch --msg-filter:

git filter-branch --msg-filter \
  'test $GIT_COMMIT = '$(git rev-list --reverse master |head -n1)' &&
echo "Nice message" || cat' master
fork0
источник
1
fork0: Отлично, спасибо. Любопытно, считается ли это «законной» практикой из-за отсутствия лучшего слова. Я имею в виду, это часто / рекомендуется делать так? Кроме того, можете ли вы делать это снова и снова в случаях с ошибочными сообщениями о фиксации? Причина, по которой я спрашиваю об этом, состоит в том, что я сначала сделал это с неправильным коммитом SHA-1, скопировав ваш фрагмент (ваш был последним коммитом, а я хотел изменить самый первый). После повторного использования команды, на этот раз с правильным SHA-1 (первая фиксация; 6707a66), это меня застало.
Хенрик
Что ж, обычное дело :) И да, можно повторить. Если вы просто добавите, -fон будет продолжать и всегда переписывать коммиты данной ветки. Значение ссылки ветки с первого раза было сохранено refs/original/masterдо того, как вы запустили команду.
fork0
Конечно, вы можете просто удалить (или переименовать) сохраненную ссылку.
fork0
2
Я обновил код, чтобы убедиться, что ошибки со скопированным идентификатором фиксации не произошло. Теперь код можно даже скопировать. Однако небольшое предупреждение : он не работает правильно, если есть более одного начального коммита (т.е. когда вы объединили две или более несвязанных веток)
fork0
3
@hced: Вы должны знать, что переписывание любого коммита, который считается «опубликованной историей», обычно является плохой идеей. В вашем случае это будет означать, что вам обычно не следует этого делать, если кто-то еще когда-либо работал над коммитом, у которого ваш корневой коммит был предком.
Марк Лонгэр
12

В pcreux есть хороший способ перефразировать первую фиксацию:

# You can't use rebase -i here since it takes the parent commit as argument.
# You can do the following though:
git checkout FIRST_COMMIT_SHA && git commit --amend && git rebase HEAD master
Дуглас
источник
3
Начиная с git 1.7.12 , git rebase -i --rootэто путь, предложенный florisla.
Дуглас