Reputation: 6180
I want to squash these four commit messages into one. The changes are already pushed.
...95c2f Merge branch 'bugfix/final' of ssh://10.0.0.30:7999/mp/web into bugfix/final
...39e3c Merge branch 'version/I2-0' of ssh://10.0.0.30:7999/mp/web into bugfix/final
...cf444 Merge branch 'version/I2-0' of ssh://10.0.0.30:7999/mp/web into bugfix/final
...43d9d C0-235, CO-236, CO-215, CO-340, CO-367, CO-368 mobile order depth etc,etc...
But if I try to do rebasing using below it ignores all merge commit messages.
git rebase -i HEAD~4
How can I achieve the same and why it is ignoring merge commits.
Upvotes: 6
Views: 14661
Reputation: 10747
As of Git(2.25.0 Release 1/13/2020 and possibly earlier) The flag --preserve-merges
is deprecated.
The Git CLI will now recommend that you use: --rebase-merges
or -r
for short
Example usage with an interactive rebase:
git rebase -i --rebase-merges HEAD~4
Check out the docs for more info:
--rebase-merges[=(rebase-cousins|no-rebase-cousins)]
By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a single, linear branch. With --rebase-merges, the rebase will instead try to preserve the branching structure within the commits that are to be rebased, by recreating the merge commits. Any resolved merge conflicts or manual amendments in these merge commits will have to be resolved/re-applied manually.
By default, or when no-rebase-cousins was specified, commits which do not have as direct ancestor will keep their original branch point, i.e. commits that would be excluded by git-log[1]'s --ancestry-path option will keep their original ancestry by default. If the rebase-cousins mode is turned on, such commits are instead rebased onto (or , if specified).
The --rebase-merges mode is similar in spirit to the deprecated --preserve-merges but works with interactive rebases, where commits can be reordered, inserted and dropped at will.
It is currently only possible to recreate the merge commits using the recursive merge strategy; Different merge strategies can be used only via explicit exec git merge -s [...] commands.
Upvotes: 11
Reputation: 489818
(It occurred to me while writing this answer that you may be conflating commits, which are the objects identified by their hash IDs, with commit messages, which are the text you wrote and stored within commits. Please keeps these separate concepts separated.)
I want to squash these four commit messages into one.
(emphasis mine). But what do you want to do with the four separate commits? Each commit saves a tree (a snapshot); what should happen to those four trees?
The changes are already pushed.
So, what should happen with the four commit hashes for those four existing commits? Is anyone else using them now?
... if I try to do rebasing using below it ignores all merge commit messages.
That's by design: it's not possible to copy a merge with any degree of faithfulness, and git rebase
means "do repeated git cherry-pick
operations to copy old-and-moldy commits to shiny new improved ones".
There is a git rebase --preserve-merges
, which does the best it can to copy the merge commits. Since that's not actually possible, it instead re-runs each merge. If you resolved merge conflicts during those merges, you will have to resolve them again.1
As evolutionxbox suggested in a comment, perhaps the outcome you want is:
...43d9d
, and the second parent of each of the three merge commits.If so, you can achieve this in several ways, though if you really like the final tree, the simplest way involves using the plumbing command, git commit-tree
.
If item 3 is wrong—if you don't want a bunch of parent commits; if what you want is the effect you would have gotten by doing a series of three git merge --squash
operations (instead of true merges) followed by an interactive rebase of all four commits—then there are again several ways to do it, though again the simplest way, at this point, involves using git commit-tree
again.
Using git commit-tree
, you tell Git to create a new commit object, whose tree you supply by hash ID, and whose parents you supply by hash ID, all on the command line. Git creates the commit object in the repository and returns to you, as the command's output, the new commit object's hash ID. You can then create or re-set a branch name to point to the new commit object. I hesitate to suggest a particular series of commands here, though, since it's still not clear what you really want to achieve.
Upvotes: 0
Reputation: 16611
Have you tried rebasing and preserving merges? Assuming you want to maintain the merge commits once rebased.
Try the following:
git rebase -i -p HEAD~4
Upvotes: 10
Reputation: 177
Merge commits are indeed not shown but they are there. There must be a cleaner solution but I remember having solved this by rebasing nevertheless (you can try to pushing an empty commit and rebasing with it for instance) even if not shown the merged commits will be included in the rebase
Upvotes: -2