3

The git book seems to contradict itself re git commit --amend:

This command takes your staging area and uses it for the commit. If you’ve made no changes since your last commit..., then your snapshot will look exactly the same and all you’ll change is your commit message.

First it says, "This command takes your staging area and uses it for the commit."

Now, if I run git add -A; git commit -m "Initial"; git status; the status message says the staging area is empty.

Then the book says, "If you've made no changes since your last commit ... your snapshot will look exactly the same..."

Now, if it uses my (empty) staging area for the commit, shouldn't the amended commit be empty? The amended commit isn't empty though, it includes the files that were in the last commit.

It seems that the git book should read:

This command takes your staging area, adds it to the last commit, and creates a new commit from the combination...

Please help me out here. What, if anything, am I missing?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • Have you seen http://stackoverflow.com/questions/25948049/git-commit-amend-in-detached-head-state/25948372#25948372? – jub0bs Sep 26 '14 at 00:28
  • @Jubobs Yes. The answers indicates that `git commit --amend` creates a new branch. Is that right? – Shaun Luttin Sep 26 '14 at 00:33
  • @ShaunLuttin Not in general; it created a new commit – Jason Baker Sep 26 '14 at 00:33
  • 1
    No. It doesn't create a new branch. Rather, the branch you're on when you amend a commit is made to point to the new commit created by `git commit --amend`. – jub0bs Sep 26 '14 at 00:34
  • @Jubobs The second graph in your answer has master pointing at `c` not at `d`. I guess that's because we're in detached HEAD. The detached HEAD part of your answer was an additional layer of complexity that the original question required and that also made the answer less clear for me. – Shaun Luttin Sep 26 '14 at 00:35
  • 1
    @ShaunLuttin Yes. The case described in my answer there is a bit special, precisely because we're in detached HEAD. But normally, the current branch is simply made to point to the new commit created by `git commit --amend`. – jub0bs Sep 26 '14 at 00:37
  • @Jubobs It would be good to have another Q&A that describes `git commit --amend` without the detached HEAD. – Shaun Luttin Sep 26 '14 at 00:38
  • @Jubobs I asked a new question: http://stackoverflow.com/questions/26050327/how-does-git-commit-amend-work-exactly – Shaun Luttin Sep 26 '14 at 00:43

1 Answers1

4

The wording is a bit awkward, but your interpretation is correct. That's exactly what --amend does.

The book seems to be saying that it won't automatically add unstaged changes to the commit.

What happens instead, as you correctly note (and as the book does say, in an unclear way in my opinion), is that the old commit is replaced with another commit, which has the same changes as the original but a (Potentially) new commit message and a new timestamp and commit hash. That's what it means by snapshot: the state of the repo at that moment in time.

Of course, if you DID have staged changes, those changes will be rolled into the new commit.

Jason Baker
  • 2,471
  • 3
  • 23
  • 28
  • 1
    The commit message may be exactly the same, actually, but the author/commit timestamps will be different from the original commit. – jub0bs Sep 26 '14 at 00:32
  • @Jubobs You're right, and I allude to that when I say that the old commit is *replaced* with a new one. I'll make that distinction mnore explicit – Jason Baker Sep 26 '14 at 00:33
  • Some suggested (edits): "which has the same changes as the original but (possibly) a new commit message, (possibly new files from the staging area), and (definitely) a new timestamp." – Shaun Luttin Sep 26 '14 at 00:39
  • I can see how that could have been confusing; I've made it more explicit, and added an interesting edge case that I came across while researching this answer – Jason Baker Sep 26 '14 at 00:42
  • `(Or even unstaged changes to a file that was modified in the commit you're ammending)` This is incorrect. `git commit` **only** works on changes staged to the index, whether or not the `--amend` option is present. – Code-Apprentice Sep 27 '14 at 03:11
  • @Code-Apprentice That's much more sensible behaviour, and it's what I did in fact observe; I need to stop answering questions so late – Jason Baker Sep 27 '14 at 03:17