1

This problem is kinda difficult to describe without sharing the full repo, but I'll try.

I realized I had made a mistake in the last but one commit. I decided to fix it using interactive rebase.

git rebase -i @~~

Now I'm taken to Vim, where I change the command in the first line:

pick 80c90b55788 First commit message  <-- change 'pick' to 'edit'
pick 712be094f96 Second commit message

Git responds with:

Stopped at 80c90b55788...  First commit message
You can amend the commit now, with
    git commit --amend 
Once you are satisfied with your changes, run
    git rebase --continue

I modify the find that needs a fix (I delete the offending line). Then I continue with:

git add <file>
git commit --amend
git rebase --continue

Now git detects a conflict in the file I edited. (Two consecutive lines were deleted - one originally in the second commit, the other one that I've deleted in the previous step.) To me, this step looks superfluous, as Git basically does the right thing - it has merged the changes correctly. But it waits for me to stage the changes.

Without any modifications to the file, I do again:

git add <file>
git commit --amend
git rebase --continue

Git reponds with:

Successfully rebased and updated refs/heads/mybranch.

BAM! Now the two commits are merged into one. The result contains changes from both commits. The first commit message is used.

What is the reason? I just wanted to modify the last but one commit and let git to rebase the second commit onto it.

jps
  • 20,041
  • 15
  • 75
  • 79
peter.slizik
  • 2,015
  • 1
  • 17
  • 29
  • [knittl's answer](https://stackoverflow.com/a/73112865/1256452) covers this, but I just want to emphasize that the requirement that you *not* use `--amend` on the conflict resolution case is bad user-experience. It's something you have to get used to in Git. – torek Jul 26 '22 at 03:35
  • @torek I checked the official documentation, `--amend` is prescribed [there](https://git-scm.com/docs/git-rebase#_interactive_mode): _By replacing the command "pick" with the command "edit", you can tell `git rebase` to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing._ – peter.slizik Jul 26 '22 at 12:40
  • Yes: but that's *only when using `edit`* (where Git stops, but not because of conflict resolution). Why? Because Git exposes you to the raw internal details of how commits work, instead of providing a proper user experience, that's why. :-) Git works pretty well (which is why it's beaten up so much of its competition), but it has a terrible set of interfaces. – torek Jul 26 '22 at 20:32
  • In particular, when rebase stops due to a conflict, the new-and-improved commit *is not yet made*. But when rebase stops because you used the word `edit`, the new-and-improved commit *is* made at that point. If you wish to replace that commit using `git commit` you must use `git commit --amend`. But when the new-and-improved commit *isn't* made yet, and you use `git commit --amend`, you're amending the *previous* commit (one that was made, or was already there), which is what people call "squashing" or a "fixup" (combining two commits). – torek Jul 26 '22 at 20:36
  • At some point (long after `git rebase --interactive` was first written) the rebase code was smartened up enough to do the appropriate kind of `git commit` for you if and when necessary, but the documentation still describes the original "the programmer must be very careful and precise about which operation he is finishing now" sequence of operations. Probably the documentation should just say "you can now edit your working tree, run `git add`, and run `git rebase --continue`" although the internal tests would need to be updated to match. – torek Jul 26 '22 at 20:40
  • @torek *But when rebase stops because you used the word edit, the new-and-improved commit is made at that point. If you wish to replace that commit using git commit you must use git commit --amend.* I agree with you. This is what I did - but it caused the problem. Today I tried to do an **edit** without following it with a `commit --amend` and it work as supposed. To rephrase my words, what I did was `git rebase -i`, select `edit`, `git rebase --continue`. And it worked. It amended the previous commit. Is this expected? – peter.slizik Jul 27 '22 at 16:58
  • Changing the command to `edit` doesn't guarantee that rebase stops *because of that change*. It might still stop *because of a conflict*. In the conflict case, you *must not* use `--amend`. If you did change the word to `edit`, the way to know why the rebase stopped is to look closely at the output message at the time the rebase stops: it either says "conflict" and stops, or it stops without saying "conflict". When it stops *without* the extra word it mentions `--amend` in the text. This is probably translated ("i18n") text and what it says in, say, German or Polish, I have no idea. – torek Jul 27 '22 at 19:44
  • As knittl said, you can just skip the `--amend` entirely and things generally work the way you want anyway. However, using `--amend` when Git stopped *because of* the `edit` keyword should also work. It's when Git stopped *regardless of* the keyword used that it won't work. – torek Jul 27 '22 at 19:46
  • Yes, it seems that `edit` works even without `--amend`. Anyway, your comments are full of insights I couldn't find elsewhere. I highly appreciate the time you took to explain it! – peter.slizik Jul 28 '22 at 08:29

1 Answers1

5

If you have conflicts while rebasing, you must not call git commit --amend. Once you have resolved the conflict and staged the changes, call git rebase --continue.

Even with action "edit", the git commit --amend step is redundant. While editing, calling git rebase --continue will automatically amend the commit being currently edited.

knittl
  • 246,190
  • 53
  • 318
  • 364
  • But... but... git says it explicitly: *You can amend the commit now, with* `git commit --amend`. *Once you are satisfied with your changes, run* `git rebase --continue`. – peter.slizik Jul 25 '22 at 18:05
  • 1
    @peter.slizik Yes, I know. I'm not sure if that's intended behavior or not. _But_ for the conflict case, if you read the message carefully, it never mentions --amend. – knittl Jul 25 '22 at 18:06