17

I'm currently in the midst of a git rebase --interactive session, where I'm editing a commit. I'm proceeding as suggested by How can I split up a Git commit buried in history? i.e. I ran git reset HEAD^ and did my modifications. Now I want rebase to continue, which requires me to commit my changes. I'd like to modify my old commit message, but the problem is, if I run git commit --amend, I'm given the commit message of the commit before the one I'm actually modifiying -- and I certainly don't want to merge my changes into that commit.

So how do I retrieve my old commit message for the commit I'm working on now?

Community
  • 1
  • 1
Bernhard Reiter
  • 771
  • 7
  • 20
  • git commit --amend should display the message of the commit you're editing (I just tried), there must be something wrong here – CharlesB May 31 '12 at 11:41
  • 1
    @CharlesB Did you try it within a workflow as described, ie after `git rebase --interactive`, `git reset HEAD^`, some modifications, and adding files back to the index? – Bernhard Reiter May 31 '12 at 11:45
  • OK, not sure if it what you want but the proposed commit message is set to `HEAD^`'s one. It perfectly makes sense to me since it is the one you want to split – CharlesB May 31 '12 at 11:56
  • the commit you marked for editing is the child of the one you want to split – CharlesB May 31 '12 at 11:57
  • I'm actually pretty sure I marked the right commit for editing, and resetting the index with `git reset HEAD^` really unstaged the changes I wanted to work on... (I'm not actually trying to split that commit, but just modifying some of the changes it introduces.) – Bernhard Reiter May 31 '12 at 12:12
  • OK, I think I can answer – CharlesB May 31 '12 at 12:17
  • @BernhardReiter please update your question to make it clear that you just want to edit the commit, not split it, and also if any of the solutions below fixed your problem, it would be helpful to other people in the future if you accepted it. –  Jul 14 '13 at 20:07

4 Answers4

24

While CharlesB's solution is correct and probably easier, the reason that the original poster is seeing the commit message before the commit he wants to edit is because he's using the --amend flag of git commit, which modifies the previous commit.

Instead of using --amend to commit your changes, just use git commit without the flag, which won't touch the previous commit. You can also pass in an option to reuse the commit message from the commit that you reset using git reset head^:

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

# Or use -C, which is the same thing, but shorter:
git commit -C HEAD@{1}

HEAD@{1} points to the commit you were at before you did git reset head^. You can also just pass in the sha id for that commit directly.

From the git commit docs:

-C <commit>
--reuse-message=<commit>

Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.

Of course, like I said, CharlesB's solution is simpler, since if you don't do the first git reset head^, you can just make changes and amend the commit you're trying to modify directly, and you automatically get the previous commit message when you do git commit --amend, you don't have to pass in the commit sha for it.

Community
  • 1
  • 1
  • 2
    does a lower case `head` actually work here? i had to use the fully capitalized version. – milkypostman Feb 18 '14 at 19:52
  • 1
    @milkypostman it actually depends on your OS and shell environment, msysgit and OS X seem to be okay with lower-case head, but Unix environments will probably only accept upper-case `HEAD`. –  Feb 18 '14 at 20:40
  • `HEAD` can be substituted for `@` in all git versions for the last few years, e.g. `HEAD@{1}` becomes `@{1}`, `HEAD~` becomes `@~`. Saves some typing. – Alex Palmer Jul 04 '17 at 10:07
  • @user456814 I suspect `head` works if your file system is case-insensitive; it is probably referring to the `.git/HEAD` file in your repo. As I've mentioned above though, if your git version is vaguely recent you can use `@` instead of `head` or `HEAD`. – Alex Palmer Jul 04 '17 at 10:11
4

Why follow instructions on commit splitting if you don't want it?

You don't reset to HEAD^, this applies only when splitting commits. Just mark the commit for editing in rebase -i, make your changes, commit --amend and rebase --continue.

Community
  • 1
  • 1
CharlesB
  • 86,532
  • 28
  • 194
  • 218
  • Couldn't you actually do `git reset head^`, but instead of using `git commit --amend`, just use `git commit`, then `rebase --continue`? Same result, wouldn't it be? –  Jul 14 '13 at 20:04
  • I find it hard to understand, how can one guess what is `HEAD^` in the middle of an interactive rebase? amending a commit is simple and clear – CharlesB Jul 15 '13 at 06:33
  • No need to guess, `git log --graph --oneline` makes it perfectly clear what `head^` is, even during `rebase -i`. But I agree, simply amending the commit is simpler. –  Jul 15 '13 at 11:50
2

I have another answer that seems to be more fool-proof, though undocumented.

$ git reset HEAD^
$ git add ...               # stage the first part of your split
$ git commit -m 'part one'
$ git commit -a -F $(git rev-parse --git-dir)/rebase-merge/message
Andrew
  • 5,611
  • 3
  • 27
  • 29
  • Again, the original poster doesn't want to split his commit, so making two commits is not the right solution. –  Jul 14 '13 at 20:31
1

I adapted some examples in git-commit(1) and git-reset(1):

$ git reset HEAD^
$ git add ...                 # stage the first part of your split
$ git commit -m 'part one'
$ git commit -a -c ORIG_HEAD  # start with the earlier commit message

If you're worried about doing something that might change ORIG_HEAD, you could instead do:

$ SAVED=$(git rev-parse HEAD)
$ git reset HEAD^
...
$ git commit -a -c $SAVED   # start with the earlier commit message
Andrew
  • 5,611
  • 3
  • 27
  • 29
  • The part of your answer that uses `commit` without the `--amend` flag is correct. However, as the original poster states in [this comment](http://stackoverflow.com/questions/10832722/how-do-i-keep-the-commit-message-when-editing-commits-via-git-rebase-interacti#comment14104282_10832722), he's not trying to split his commit, so making two separate commits is not the right solution. –  Jul 14 '13 at 20:10
  • 1
    Also, in your answer, `ORIG_HEAD` points to ***the first commit*** that the original poster was on before he started rebasing. If he's editing a commit that's an ancestor of `ORIG_HEAD`, then `ORIG_HEAD` ***will not contain the original message*** for the ancestor, in which case that part of your solution will be incorrect. –  Jul 14 '13 at 20:12
  • I've answered the question as it is written, which I think is fair. Original poster is free to edit it. :-) And thanks for the correction--`ORIG_HEAD` is assuming the `git reset HEAD^` has already happened, which is not what I wrote. Fixed now. – Andrew Jul 15 '13 at 22:14
  • I had meant to take another look at this a long while back. I'm not sure anything I mentioned to you in my comments was correct, so your answer may have been just fine as it was. –  Aug 10 '15 at 22:15