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, mergebranch2it:git checkout branch1 git merge branch2that yield
a---b------c--d---e [head=branch1] / x---y--z------- [branch2]now, know that's not want, bear me second. use merge commit
ehave access "the ancestry on both sides" @ once.check out
branch2, reset commita.git checkout branch2 git reset --hardyou'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
branch1notbranch2:git rev-list --no-merges --reverse branch2..branch1this should yield following list of commits:
x,b,y,z,c,d; commite, created in step 1 not in list, because used--no-mergesflag.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 branch1edit: correctly remarked, because
branch1not merged current branch (branch2), using-dwon't do, here; need use-dflag 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
branch1branch1.(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