You have a couple options, but I want to address a matter of "how git works" first, as it may help you decide which way to go...
I have the following git structure:
A -> B -> C -> D -> E -> F
\
G
...
how do you merge it in such a way that it ends up like the following:
A -> B -> G -> C -> D -> E -> F
As written, this isn't possible. It may seem like I'm splitting hairs, because you could rewrite history to get something very similar, e.g.
A -> B -> G -> C' -> D' -> E' -> F'
But that's actually different in a very important way: It means that every commit from C
onward was removed from history and replaced with a new commit, and assuming this is a shared repo, you'll end up with force a push which will cause problems for all other clones. See the section "recovering from upstream rebase" in the git rebase docs for an explanation of the issue: https://git-scm.com/docs/git-rebase
(The reason those commits are replaced is that a commit's history - i.e. what commits led up to it - is an integral part of the commit.)
Option 1 - reparent
So, with an understanding of that issue if you still want to make that change, what you're talking about is reparenting C
. This is similar to a rebase, except that you're ignoring the changes that G
would apply - effectively reverting them. (This might make sense if your normal workflow relies on rebasing branches to form a linear history, as this is basically the rebase equivalent to merge --ours
.)
But how to do it? Up until recently I'd have suggested git filter-branch
, but it seems that's fallen out of favor and the new shiny thing is git filter-repo
; you can read about how to use it here: https://github.com/newren/git-filter-repo Warning: it's a very general-purpose tool, so that doc isn't exactly focused on just the operation you want to perform; but specifically because it's a very general and potentially dangerous tool, if you're going to use it then you should learn more about it than one recipe I would type into an answer.
Option 2 - merge
On the other hand, you refer to what you're wanting as a merge, which suggests that you use a merge-based workflow (rather than a rebase-and-fast-forward workflow). That is, maybe your diagram was just a misinterpretation and the above was all for naught.
If you normally would merge branches back together, then here you can say
git merge --ours branch
and git will create a merge commit but will ignore any changes from the branch being merged in
A -> B -> C -> D -> E -> F -> M(!G)
\ /
G ---------------------
This is only really important if you don't like having the diverging branch. That is, this is exactly what --ours
merges are for, but then again --ours
merges are only important if your team decides they're important.
Option 3 - Do nothing
Generally it won't hurt anything. It does mean that reports of unmerged branches would forever include the patch reelase branch.