150

As Git user I regular come across the situation, that I need to rework one or more commits in a way which do not fit into --amend or rebase -iwith fixup commits. Typically I would do something like

git reset HEAD~1
# hack, fix, hack
git commit -a
# argh .. do I need to retype my message?

I take sensible composed commit messages quite serious. They typically contain larger text with references & justifications for the change. Until now, I'm quite annoyed on the lengthy process to recover my old commit message via an unsorted git reflog, git logand copy & paste process.

Is there a better to tackle this? And how would it, if my comprises more than one commit?

Edit: After a bit thinking about this I think what I'm looking for is some git stash-like functionality for commit messages where fixup/amend commits are not appropriate.

bentolor
  • 3,126
  • 2
  • 22
  • 33
  • 2
    If all you did was `git reset head~1`, wouldn't your old commit message just be the 2nd entry in the `reflog`? –  May 31 '13 at 13:51
  • Yes - but how would I be able to reuse the message without copy & pasting (which typically requires manual unindenting) – bentolor Jun 01 '13 at 22:53
  • Nowadays, just have `gitk` open. That way you won't even have to use the reflog. Alternatively, use `rev-parse ` to get your hash before the reset and use the answer by ibizaman. – cst1992 Nov 18 '16 at 06:01

4 Answers4

203

After a git reset, this one-liner can do it:

git commit --reuse-message=HEAD@{1}

or even shorter:

git commit -C HEAD@{1}

You can use the other options given by @user2718704.

Community
  • 1
  • 1
ibizaman
  • 3,053
  • 1
  • 23
  • 34
53

When running "git commit" command, you've to check the following options,

To reuse,

--reuse-message=<commit>

To edit on reuse,

--reedit-message=<commit>

To change the author,

--reset-author
user2718704
  • 753
  • 7
  • 9
12

Why reset if you can hack, fix, hack and then just run git commit --amend --no-edit; thus, retaining your original commit message.

To make it work for multiple commits, just create a temporary commit with your newest changes and then use an interactive rebase to squash the previous commit (containing the good commit message) with the new temporary one, keeping the commit message of the old commit.

mart1n
  • 5,969
  • 5
  • 46
  • 83
  • 3
    When doing an interactive rebase, you can even use the `fixup` instruction to declare that the later commit is to fix the previous commit and it will automatically use the commit message from the original discarding the message from the fixup commit. – qqx May 31 '13 at 14:29
  • 1
    For example if I want to re-merge an force-updated pull-requests. Or if the commit is not the last one and cannot be easily fixed based on HEAD and its easier to redo them. – bentolor Jun 01 '13 at 23:17
  • @BenTebulin Well, interactive rebase lets you modify any commit in a range of specified commits. It's not strictly the HEAD commit that has to be modified. – mart1n Jun 02 '13 at 06:47
  • @mart1n Thanks for singling out _edit_ in `rebase -i`. Never used it in that context. For the remaining cases like re-merging the other answer is more appropriate to my question, so I marked that one as answer. – bentolor Jun 02 '13 at 14:09
  • Intellij has scopes that only operate on files that haven't been committed yet. Its useful to reset the files to uncommitted so that intellij can be instructed to lint the files, for example, and then re-commit those files with the same message. amend wont work for that due to limitations of intellij's scoping. – David Mann Sep 10 '18 at 21:10
6

You could consider git commit --reset-author -c <commit>, to reuse the commit message with editing and the current time.

Joe
  • 29,416
  • 12
  • 68
  • 88