git - How can I "splice" two (or more) completely unrelated linear branch ancestries into a new one? -
i'm trying combine 2 branches each different root commit new, empty branch. not usual merge thing don't want have branches combined in last commit (in case, new branch have merge commit , 'below' still 2 seperate histories. new branch still have 2 root commits.).
one important fact in scenario both branches unrelated. none commit of either branch affects pathes of other branches' commits => there no conflicts.
let's assume following branches:
a---b-----c-d x---y-z
this looking for:
a-x-b-y-z-c-d
the main point want have commits in chronological order. how achieve?
you write:
one important fact in scenario both branches unrelated. no commit of either branch affects patches of other branches' commits => there no conflicts.
of course, "splicing" operation suggest bad idea if anticipate many conflicts arise. let's assume that, indeed, nothing bad happen.
if, @ beginning, repo looks this
a---b------c--d [branch1] x---y--z [branch2]
you can follow procedure outlined below automatically "splice" commits both branches single branch, while maintaining chronological order.
"splicing" 2 unrelated branches
make sure you're in clean working state; check out
branch1
, mergebranch2
it:git checkout branch1 git merge branch2
that yield
a---b------c--d---e [head=branch1] / x---y--z------- [branch2]
now, know that's not want, bear me second. use merge commit
e
have access "the ancestry on both sides" @ once.check out
branch2
, reset commita
.git checkout branch2 git reset --hard
you'll in following situation:
a [head=branch2] \ ---b------c--d---e [branch1] / x---y--z-------
generate list (in chronological order) of non-merge commits reachable
branch1
notbranch2
:git rev-list --no-merges --reverse branch2..branch1
this should yield following list of commits:
x
,b
,y
,z
,c
,d
; commite
, created in step 1 not in list, because used--no-merges
flag.cherry-pick commits on top of
branch2
(a).git cherry-pick `git rev-list --no-merges --reverse branch2..branch1`
your repo follows:
a--x'--b'--y'--z'--c'--d' [head=branch2] \ ---b-----c-d---e [branch1] / x---y-z------
delete
branch1
:git branch -d branch1
edit: correctly remarked, because
branch1
not merged current branch (branch2
), using-d
won't do, here; need use-d
flag instead.your repo be
a--x'--b'--y'--z'--c'--d' [head=branch2]
(optionally) rename
branch2
:git branch -m branch2 <more_meaningful_name>
generalization more 2 branches
let's assume have n unrelated branches: branch1
, branch2
, ..., branchn
, branch1
corresponds branch root commit oldest commit in entire repository; let's call commit a
.
a ----- o ---- o [branch1] o ----- o ---- o -- o [branch2] ... o ----- o - o [branchn]
if don't know commit a
, can identify running
git rev-list --reverse --max-parents=0 --all
the commit id of a
first listed in output of command. , can identify branch branch1
running:
git branch -r --contains `git rev-list --reverse --max-parents=0 --all | head -1`
then procedure outlines in two-branch case becomes:
create commit has access ancestry of branches, merging branches other
branch1
branch1
.(same in two-branch case)
- (same in two-branch case)
- (same in two-branch case)
- delete branches other
branch2
. - (same in two-branch case)
Comments
Post a Comment