Jak przeformułować pierwszy komunikat o zatwierdzeniu git?

116

Mam drzewo robocze zawierające 3 commmity:

➜ ~ myproject git: (mistrz) git log

commit a99cce8240495de29254b5df8745e41815db5a75
Author: My Name <[email protected]>
Date:   Thu Aug 16 00:59:05 2012 +0200

    .gitignore edits

commit 5bccda674c7ca51e849741290530a0d48efd69e8
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:36:39 2012 +0200

    Create .gitignore file

commit 6707a66191c84ec6fbf148f8f1c3e8ac83453ae3
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:13:05 2012 +0200

    Initial commit (with a misleading message)

Teraz chcę reword otrzymać wiadomość o zatwierdzeniu mojego pierwszego zatwierdzenia (6707a66)

➜ ~ myproject git: (mistrz) git rebase -i 6707

(… Wchodząc w 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

W tym przypadku chcę poprawić (reword w języku git) omawiany komunikat dotyczący zmiany:

Początkowe zatwierdzenie (z mylącą wiadomością)

… Do czegoś odpowiedniego.

Nic dziwnego, że moja powyższa próba nie powiodła się, ponieważ pierwsze zatwierdzenie oczywiście nie ma żadnego zatwierdzenia rodzica . (A kiedy rebasemusisz odwołać się do następnego najstarszego zatwierdzenia przed tym, który chceszreword , prawda?)

Istota mojego pytania, czy można to osiągnąć w jakikolwiek inny sposób?

Henrik
źródło
Lub możesz po prostu zostawić to na zawsze jako repozytorium tandetne dziwactwo.
Christopher
4
możliwy duplikat Zmiana wiadomości pierwszego zatwierdzenia? (git)
Mark Longair
^ Bardzo prawda ... Myślałem, że dobrze szukałem tego konkretnego pytania, ale jest to to samo co moje. Jest dużo doskonalenia copywritingu mojego pytania. :-P
Henrik
1
@hced: :) Twoje copywriting nie idzie na marne - pomoże innym ludziom znaleźć rozwiązanie w przyszłości, nawet jeśli
miałoby
2
Każdy, kto trafi na to pytanie, może znaleźć moją odpowiedź na temat Zmiana przesłania pierwszego commita? (git) być pomocnym.

Odpowiedzi:

215

Robić git rebase -i --root

(wskaż rootzamiast wskazywać na konkretne zatwierdzenie)

W ten sposób pierwszy zatwierdzenie jest również dołączone i możesz rewordgo tak po prostu jak każdy inny.

--rootOpcja została wprowadzona w Git v1.7.12(2012). Wcześniej jedyną opcją było użycie filter-branchlub --amend, co jest zwykle trudniejsze do wykonania.

Uwaga: zobacz także to podobne pytanie i odpowiedź .

florisla
źródło
12

Zawsze możesz użyć 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
widelec0
źródło
1
fork0: Świetnie, dzięki. Ciekawe, czy należy to uznać za „uprawnioną” praktykę, z braku lepszego słowa. To znaczy, czy jest to powszechne / zalecane, aby to zrobić w ten sposób? Czy możesz to powtarzać wielokrotnie w przypadku błędnych komunikatów o zatwierdzeniach? Powód, dla którego o to pytasz, jest taki, że najpierw zrobiłem to z niewłaściwym zatwierdzeniem SHA-1, kopiując twój fragment (twój był najnowszym zatwierdzeniem, podczas gdy ja chciałem zmienić pierwszy). Po ponownym użyciu polecenia, tym razem z poprawnym SHA-1 (pierwsze zatwierdzenie; 6707a66), zaatakowało mnie.
Henrik
Cóż, to jest powszechne :) I tak, możesz to powtórzyć. Jeśli tylko dodasz, -fto będzie kontynuowane i zawsze przepisze commity z danej gałęzi. Wartość odniesienia gałęzi od pierwszego razu została zapisana w programie refs/original/masterprzed uruchomieniem komendy.
widelec 0
Oczywiście możesz po prostu usunąć (lub zmienić nazwę) zapisanego odniesienia.
widelec 0
2
Zaktualizowałem kod, aby upewnić się, że błąd ze skopiowanym identyfikatorem zatwierdzenia się nie zdarzy. Teraz kod można nawet skopiować i wkleić. Jednak słowo ostrzeżenia : nie działa poprawnie, jeśli istnieje więcej niż jedno wstępne zatwierdzenie (tj. Gdy połączyłeś dwie lub więcej niepowiązanych gałęzi)
fork0
3
@hced: Powinieneś być świadomy, że przepisanie dowolnego zatwierdzenia, które jest uważane za „opublikowaną historię”, jest zwykle złym pomysłem. W twoim przypadku oznaczałoby to, że generalnie nie powinieneś tego robić, jeśli ktokolwiek inny pracowałby nad zatwierdzeniem, które miało twoje rootowanie jako przodek.
Mark Longair,
12

Istota pcreux ma dobry sposób na przeformułowanie pierwszego zatwierdzenia:

# 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
Douglas
źródło
3
Począwszy od git 1.7.12 , git rebase -i --rootjest droga, jak sugeruje florisla.
Douglas,