1

I have a branch with some regular commits and one merge-commit from the develop branch. There were conflicts that were successfully resolved during the merge.

* 18b0bd7 (HEAD -> my_branch, origin/my_branch) My commit №6
* b7c7d02 My commit №5
* bd4b580 My commit №4
*   c902168 Merge remote-tracking branch 'develop' into my_branch // THERE'RE SOME SUCCESSFULLY RESOLVED CONFLICTS!
|\  
| * 3428461 Commit №3 from develop
| * e40fc07 Commit №2 from develop
| * 48697c2 Commit №1 from develop
* | dac8571 My c0mdiT №3
* | 1cf1712 My commit №2
* | 6aa6a86 My commit №1

I want to edit message of dac8571. In cases like that I usually set the branch head at it, use git commit --ammend ... and then git rebase ... to move upstream commits onto the edited one. But the problems start when I try to edit a commit before merge-commit with resolved conflicts. Git forces me to resolve them again, but that's not an option for me because they're already resolved in my_branch. All I have to do is change the commit description of the commit in the middle of my_branch and resolve the merge conflicts in the same way they are already resolved. I don't need to make changes to the code of those commits.

How can I achieve it? I spent a lot of time trying to use cherry-pick, rebase --merge-merges, rerere, but I didn't get it to work properly. Some of these things are too complicated for me, and others I most likely use incorrectly. Could you, please, explain to me clearly how to change the commit message before the merge commit?

RareScrap
  • 541
  • 1
  • 7
  • 17
  • Using [git-filter-repo](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html) can do this, though admittedly it feels like using a sledgehammer to kill a fly. But if all the fly swatters have big holes in them... – TTT Sep 15 '22 at 16:38
  • Are you able to provide a link to a repository that reproduces this problem? – larsks Sep 15 '22 at 17:31

2 Answers2

2

It can be done with some work

git checkout dac8571
git commit --amend
# let's create a new revision for c902168 using HEAD as the first parent
git commit-tree -p HEAD -p 3428461 -m "some comment" c902168^{tree}
# previous command will output a revision ID
git rebase --onto the-revision-id-from-commit-tree c902168 my-branch

And that's it

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • This is cool. I wish `rebase --rebase-merges` would at least check to see if the previous merge-commit's parents had the identical states as the current parents, and if so, re-use the merge-commit's tree like you did here. I'm not sure how often people wish to rebase in order to change only meta data without changing state, but surely it happens often enough to at least handle it, and it seems like it would be relatively straight forward to do. – TTT Sep 15 '22 at 19:30
  • 1
    I sent one proposal about this topic to git and was asked to improve on my patch. When I am inspired again, will sit down to work on it. Messing up with `sequencer.c` is not the easiest thing to do. :-D – eftshift0 Sep 15 '22 at 19:33
  • ... not exactly this topic, now that I recall. No changing the metadata from commits, other than parents so this case would still have to be hacked, anyway. – eftshift0 Sep 15 '22 at 19:36
  • You really saved my day, thank you! Also I would recommend to use `--committer-date-is-author-date` to keep author date same as commit date (git apply a new commit date to rebased commit, you can read about it [here](https://stackoverflow.com/questions/11856983/why-is-git-authordate-different-from-commitdate)) and `--reapply-cherry-picks` to not to skip other merge commits. – RareScrap Sep 22 '22 at 14:21
0
git replace --edit dac8571
git filter-branch

and for the log you've shown here that'll do it. If the history's really long git filter-branch -- dac8571^! @ to stop looking for stuff that needs fixing at its parents (there's only one here, ^! gets them all however many there are).

jthill
  • 55,082
  • 5
  • 77
  • 137