3

I have two branches that effectively contain the same files, but that are separate for legacy reasons. Call them A and B.

If I run git log --oneline A ^B Git outputs 114 commits, which is expected.

I can then run git merge -s ours --allow-unrelated-histories A while on branch B which indicates to Git that A has already been merged into B without making any changes to the end file state. This works, except that B now receives those 114 commits as part of its history (git log).

How can I mark A as being merged to B without bringing in all of A's history as well?

I tried git merge --squash -s ours --allow-unrelated-histories A followed by git commit, but that doesn't have any effect.

Conceptually squashing the -s ours commit should give me exactly what I want, but it doesn't work.

Zecrates
  • 2,952
  • 6
  • 33
  • 50

1 Answers1

5

How can I mark A as being merged to B without bringing in all of A's history as well?

You can't. When git says that A is merged to B, it means that the As history is reachable from B.

You could use git log --first-parent to avoid following the merged-in history (if this doesn't omit other history you need at other merge commits).

You could discard branch A entirely. (If you don't want it showing up as an unmerged branch, and you don't want to see its history, then what do you want it for?)

If you do want to archive As history, but don't normally want to see it, you could either migrate it to an archive repo where it normally won't be seen, or replace the branch with a tag (since there should be no reason to continue advancing the A ref if it's just archival), and then at least it isn't an "unmerged branch".

I guess a little extra background... The reason "squash merging" doesn't work here is because it doesn't produce a merge at all. Given

... x -- x -- A <--(A)

... x -- x -- B <--(B)

a normal merge would produce

   ... x -- x -- A <--(A)
                  \
... x -- x -- B -- M <--(B)

and a normal squash merge would produce

... x -- x -- A <--(A)

... x -- x -- B -- M <--(B)

The difference is that M is not a merge. It has the same content (technically, the same TREE object) as a merge would, but it only preserves the first parent; so after the fact, git doesn't "remember" that it has anything to do with A.

In the case where you told git to keep the content from B (-s ours), the TREE is taken from B. Combining that with squash would create an "empty" commit - as you observed, it does nothing.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52