I know that I can use git commit --amend --file=path-to-my-new-message
but this will amend staged changes, too. Of course, I could stash and later apply&drop the stash, but is there a quicker solution to change the HEAD commit message without committing the staged changes (and user interaction)?
![](../../users/profiles/209706.webp)
- 24,166
- 22
- 78
- 117
-
This is a good question, and I bet there's a way to do it, but since it's such an infrequent operation I'm guessing I'd never remember the command line parameters to do it. Stash/amend/pop is probably a lot more practical. – Dan Breen Dec 27 '11 at 16:22
3 Answers
You can write a new commit message to a file (say msg.txt
) and use git commit-tree
, e.g.
new_head=$(git commit-tree HEAD^{tree} -p HEAD^ <msg.txt)
git reset --soft $new_head
This assumes that the commit you are amending has one parent, if not you need to supply further -p HEAD^2 -p HEAD^3 ...
.
It's a bit ugly and low level. You might find it easier to stash your changes and use a straight "amend".
git stash
git commit --amend
git stash pop --index
As @Jefromi suggests, you could also use a temporary index file for the amend operation, e.g.
GIT_INDEX_FILE=.git/tmpidx git reset
GIT_INDEX_FILE=.git/tmpidx git commit --amend
rm .git/tmpidx
![](../../users/profiles/19563.webp)
- 648,528
- 94
- 608
- 638
-
You could also kludge around with GIT_INDEX_FILE, I bet! But this seems cleaner to me. – Cascabel Dec 27 '11 at 16:57
-
Instead of HEAD^, HEAD^2, ... can I use the SHA IDs of the parent commits of the existing HEAD commit? – Mot Dec 27 '11 at 19:26
-
@Mike L.: Well, yes but why would you? `HEAD^n` is going to be shorter to type and you aren't going to have to look it up. – CB Bailey Dec 27 '11 at 21:22
-
-
@Jefromi: Actually, I like your GIT_INDEX_FILE solution, it seems quite clean. – CB Bailey Dec 28 '11 at 15:11
-
@MikeL.: OK, but I suspect that 95% of the time it'll be a commit with one parent and you'll know this and 99% of the rest of the time it'll be a simple 2 parent merge. – CB Bailey Dec 28 '11 at 15:15
-
@MikeL: You could do it all at once: `git reset --soft $(git commit-tree $(git log -n 1 --pretty=%P | sed 's/\(^\| \)/&-p /g') < msg.txt)` (The %P format placeholder is expanded to the SHA1s of the parents, and git log by default starts from HEAD, giving you what you need.) – Cascabel Dec 28 '11 at 15:15
-
-
@Charles: Oops, my bad. I'll fix it. (If you don't want to mess with stuff like that, I agree that you don't need to look up SHA1s - the commit message should be plenty to distinguish between simple commit, normal merge, and octopus merges - the default octopus merge message lists the branches in the subject just like the normal merge one does.) – Cascabel Dec 28 '11 at 15:18
According to the man page git commit --amend --only
without any paths specified should do the job, however this doesn't work for me. As a work-around you may temporarily add a file and remove it again, amending two times:
touch tmp
git add tmp
git commit --amend -m "new message" tmp
git rm tmp
git commit --amend -m "new message" tmp
![](../../users/profiles/241453.webp)
- 15,236
- 6
- 50
- 77
You can git rebase -i HEAD^
and then change pick
to reword
in the editor opened by git-rebase. After this you will be prompted for a new commit message.
![](../../users/profiles/298479.webp)
- 285,213
- 77
- 557
- 610
-
Interactive rebase is no option for me, because the command has to be run without user interaction. – Mot Dec 27 '11 at 19:27