git rebase --interactive (reword) left me with two trees with same commit messages

968 Views Asked by At

I wanted to reword my commit messages. I used git rebase --interactive, and used reword to alter commit messages. My expectations were that my tree will remain exactly the same, but with different commit messages. Instead, I ended up with 2 trees, one containing the original messages, one reworded ones.

I've edited the tree below to remove complexity, so maybe it is not a truest representation of where things went wrong, and why, but it is a clear representation of what I have right now. Notice that there are 4 messages the are the essentially the same, but are slightly reworded. I assure you that deltas are the same.

* 56bb877 (HEAD, bjyGuardProvider) BjyRuleAdapter:  checkpoint!  (same as 0e1f985)
* 6b765f1 Base:  Added a new FedcoUser local module (same as 47e1cf9)
* bbfb764 Base:  Added Zend Studio/Server deployment descriptor files (same as 6b7cc21)
* 8ee08b9 General:  Added vendor modules (no configuration applied) (same as 4648e11)
| * 0e1f985 (origin/bjy, bjy) Checkpoint:  BjyAuthorize works
| * 47e1cf9 Added a new FedcoUser local module
| * 6b7cc21 Added Zend Studio/Server deployment descriptor files
| * 4648e11 Added vendor modules (no configuration applied)
|/
* e539e7a Initial ZendSkeletonApplication

How do I fix this?

If it absolutely will help, I can put a link to the full tree somewhere, or provide any other info.

2

There are 2 best solutions below

0
On

This is in fact a normal consequence of rebase, which does not modify existing commits, but instead adds new ones. You had this:

A - B - C - D - E   <-- origin/bjy, bjy, HEAD=bjyGuardProvider

where commit A is the Initial ZendSkeletonApplication one, B is Added vendor modules, and so on.

You then did a git rebase -i of commits B through E, while HEAD was telling git that the current branch is bjyGuardProvider. Rebase copied B through E (hence the same trees) to new commits with new commit IDs, and made branch label bjyGuardProvider point to the end of the new chain:

A - B - C - D - E   [the old tip commit]
  \
    B'- C'- D'- E'  <-- HEAD=bjyGuardProvider

But it will not (and should not) move any other branch labels ... so bjy and origin/bjy remain attached to commit E, on the old chain.

If you move your own bjy label (manually) and force-push this to the git repository on origin, you may (depending on how permissive origin is) be able to move all three labels to point to commit E'. The old chain will no longer have any labels, and will be eligible for garbage collection, if those are indeed the only three labels that used to name those commits.

If some third repository has a copy of the origin repository, however, they will still have the old labels and the old commits, and you will need to have them move their labels as well. As @poke noted in a comment, this is why rebasing published commits is discouraged. ("Should" and "should not" are ultimately value judgements—is the pain of getting all other repositories in sync, worth the benefit, whatever it is?—but the pain is as you have now seen.)

0
On

Did you do some pull or fetch and merge afterwards? The tree looks like this.

After rewriting your history with git rebase the names (hashes) of the first commit and all following commits will change, which causes git push to fail it --force is not specified.

pulling new commits afterwards will reintroduce all the commits that should be changed.

To fix your branch you can rebase again, do a forced push and remember to never ever rewrite pushed branches again!