Paul L
Paul L

Reputation: 938

git squash several merge commits

I checked out a local branch, made several commits to it, and then pushed my branch to origin. My boss wanted to merge my branch into master, but was apparently under the impression that he had to merge every commit individually, rather than just merging my pushed branch's tip into master. As a result, our git history now looks like this: branch names changed to protect boss's reputation in the company

Is there a "right" way to fix up the history so that it only shows one merge commit, that of my origin/pl/EngATSDataOnChkPrint branch into origin/master? I suspect it's going to involve some sort of git rebase -i with some squash's, but I'm weary to try such a thing without getting some advice first (I'm better at git than my boss, but not by a whole lot...)

Thanks!

Upvotes: 1

Views: 93

Answers (2)

torek
torek

Reputation: 487725

TL;DR version: you can clean this up, but you probably should not, as too many people may already depend on the mess. If it's only two people, maybe that's not too many; that part is something you must decide (preferably with them).


These commits are published, and you and several other people have picked them up (we know of two at least, namely you and your boss).

You can redo everything to produce fewer or no merges, but if you do so, anyone who has picked up the merges will have to do some work to adjust their repositories as well. The reason is simple: git only ever adds new stuff to the repository, it never actually removes anything.1

You can therefore use git reset to "discard" some merges, then make new ones, but your repository still has the original merges ... and anyone who picked them up, also still has them, and may have done work that depends on them. If so, they will re-introduce those commits when they merge their work with what you think you removed (but they still have), which means that they need to know not to merge their work with your sort-of-but-not-really-removed work.

Specifically, they will need to rebase their work on the old work, or on the new replacement you have put in its place, whichever is the case by the time they get around to this.

The same goes if you choose to rebase your work after, or as part of, removing these merges. (Normally rebase discards merges.) This is because rebase works by copying the old commits to new ones, with new IDs and new parent-IDs.

Say, for instance, that you have three commits and you want to move (rebase) them. The first "moved" commit must be copied so that it can have a new parent-ID, and this gives it a new ID of its own. This means the second commit must also be copied so that it can have the first copy's new ID as its parent, and that gives the second copy a new ID. Then the third commit must be copied so that it can have the second new ID as its parent:

(before):

... <- o <- o <- o     <-- master
        \
         o <- o <- o   <-- yourbranch

(after copying):

... <- o <- o <- o               <-- master
        \         \
         \         o <- o <- o   <-- yourbranch [copies]
          \
           o <- o <- o          [abandoned originals]

If no one else has these commits—which is certainly true if they are not published—then copying them and forgetting the original IDs is fine. If someone else has the originals, though, they may re-introduce them.


1What, never?

No, never!

What, never?

Well, hardly ever!

(More precisely, stuff that appears to be removed is usually just hidden away, where it remains for 30 days or so until git decides that it has been long enough to really recycle it as garbage.)

Upvotes: 2

kan
kan

Reputation: 28951

rebase usually removes merge-commits, as rebased commits are linear and no need to have a merge. Just try and see results, use reflog and reset if something goes wrong to undo your bad experiments.

The thing is that seems the history is already pushed into a public repository (origin) so in this situation you have to do a force-push which is usually bad for a public history. If I were you, I would keep it as is. History looks weird, but it is not bad.

Upvotes: 0

Related Questions