@ibgib/vcs-gib 0.0.21 → 0.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/VCS_CLI_USER_GUIDE.md +94 -89
- package/dist/AUTO-GENERATED-version.d.mts +1 -1
- package/dist/AUTO-GENERATED-version.mjs +1 -1
- package/dist/bootstrap/node-bootstrap.mjs +1 -1
- package/dist/cli/cli-arg-parser.d.mts +1 -0
- package/dist/cli/cli-arg-parser.d.mts.map +1 -1
- package/dist/cli/cli-arg-parser.mjs +5 -1
- package/dist/cli/cli-arg-parser.mjs.map +1 -1
- package/dist/cli/cli-constants.d.mts +6 -0
- package/dist/cli/cli-constants.d.mts.map +1 -1
- package/dist/cli/cli-constants.mjs +12 -0
- package/dist/cli/cli-constants.mjs.map +1 -1
- package/dist/cli/commands/add-cmd.d.mts.map +1 -1
- package/dist/cli/commands/add-cmd.mjs +5 -2
- package/dist/cli/commands/add-cmd.mjs.map +1 -1
- package/dist/cli/commands/commit-cmd.d.mts +5 -4
- package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
- package/dist/cli/commands/commit-cmd.mjs +149 -33
- package/dist/cli/commands/commit-cmd.mjs.map +1 -1
- package/dist/cli/commands/generate-comment-cmd.d.mts +19 -0
- package/dist/cli/commands/generate-comment-cmd.d.mts.map +1 -0
- package/dist/cli/commands/generate-comment-cmd.mjs +140 -0
- package/dist/cli/commands/generate-comment-cmd.mjs.map +1 -0
- package/dist/cli/commands/log-cmd.d.mts +12 -3
- package/dist/cli/commands/log-cmd.d.mts.map +1 -1
- package/dist/cli/commands/log-cmd.mjs +236 -38
- package/dist/cli/commands/log-cmd.mjs.map +1 -1
- package/dist/cli/commands/merge-cmd.d.mts +21 -8
- package/dist/cli/commands/merge-cmd.d.mts.map +1 -1
- package/dist/cli/commands/merge-cmd.mjs +138 -70
- package/dist/cli/commands/merge-cmd.mjs.map +1 -1
- package/dist/cli/commands/status-cmd.d.mts +5 -6
- package/dist/cli/commands/status-cmd.d.mts.map +1 -1
- package/dist/cli/commands/status-cmd.mjs +50 -205
- package/dist/cli/commands/status-cmd.mjs.map +1 -1
- package/dist/cli/vcs-cli-main.d.mts.map +1 -1
- package/dist/cli/vcs-cli-main.mjs +27 -6
- package/dist/cli/vcs-cli-main.mjs.map +1 -1
- package/dist/engine/index/index-helper.d.mts.map +1 -1
- package/dist/engine/index/index-helper.mjs +3 -0
- package/dist/engine/index/index-helper.mjs.map +1 -1
- package/dist/engine/item/item-helper.d.mts +31 -1
- package/dist/engine/item/item-helper.d.mts.map +1 -1
- package/dist/engine/item/item-helper.mjs +44 -2
- package/dist/engine/item/item-helper.mjs.map +1 -1
- package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts +74 -0
- package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts.map +1 -0
- package/dist/engine/merge/{b2tfs-3way-merge-strategy.mjs → b2tfs-3way-graft-strategy.mjs} +133 -304
- package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs.map +1 -0
- package/dist/engine/merge/{b2tfs-3way-merge-types.d.mts → b2tfs-3way-graft-types.d.mts} +2 -9
- package/dist/engine/merge/b2tfs-3way-graft-types.d.mts.map +1 -0
- package/dist/engine/merge/b2tfs-3way-graft-types.mjs +2 -0
- package/dist/engine/merge/b2tfs-3way-graft-types.mjs.map +1 -0
- package/dist/engine/status/status-helper.d.mts +89 -0
- package/dist/engine/status/status-helper.d.mts.map +1 -0
- package/dist/engine/status/status-helper.mjs +285 -0
- package/dist/engine/status/status-helper.mjs.map +1 -0
- package/dist/test/test-helpers.d.mts +51 -0
- package/dist/test/test-helpers.d.mts.map +1 -0
- package/dist/test/test-helpers.mjs +135 -0
- package/dist/test/test-helpers.mjs.map +1 -0
- package/package.json +4 -4
- package/src/AUTO-GENERATED-version.mts +1 -1
- package/src/bootstrap/node-bootstrap.mts +1 -1
- package/src/cli/cli-arg-parser.mts +5 -0
- package/src/cli/cli-constants.mts +13 -0
- package/src/cli/commands/add-cmd.mts +5 -2
- package/src/cli/commands/branch-checkout-cmd.respec.log +8 -101
- package/src/cli/commands/branch-checkout-cmd.respec.mts +11 -10
- package/src/cli/commands/commit-cmd.mts +165 -42
- package/src/cli/commands/commit-log-cmd.respec.mts +216 -3
- package/src/cli/commands/generate-comment-cmd.mts +171 -0
- package/src/cli/commands/log-cmd.mts +288 -41
- package/src/cli/commands/merge-cmd.mts +154 -76
- package/src/cli/commands/status-cmd.mts +57 -256
- package/src/cli/vcs-cli-main.mts +28 -7
- package/src/engine/index/index-helper.mts +3 -0
- package/src/engine/item/item-helper.mts +76 -3
- package/src/engine/merge/{b2tfs-3way-merge-strategy.mts → b2tfs-3way-graft-strategy.mts} +152 -374
- package/src/engine/merge/{b2tfs-3way-merge-strategy.respec.mts → b2tfs-3way-graft-strategy.respec.mts} +27 -122
- package/src/engine/merge/{b2tfs-3way-merge-types.mts → b2tfs-3way-graft-types.mts} +34 -42
- package/src/engine/merge/b2tfs-sync-comments.respec.mts +399 -0
- package/src/engine/status/status-helper.mts +380 -0
- package/src/test/test-helpers.mts +168 -0
- package/tsconfig.test.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts +0 -48
- package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts.map +0 -1
- package/dist/engine/merge/b2tfs-3way-merge-strategy.mjs.map +0 -1
- package/dist/engine/merge/b2tfs-3way-merge-types.d.mts.map +0 -1
- package/dist/engine/merge/b2tfs-3way-merge-types.mjs +0 -2
- package/dist/engine/merge/b2tfs-3way-merge-types.mjs.map +0 -1
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
* @module merge-cmd
|
|
3
3
|
*
|
|
4
4
|
* Command handler for `vcs merge <branchName>`.
|
|
5
|
-
* Merges
|
|
6
|
-
*
|
|
5
|
+
* Merges the incoming branch into the base (active/current) branch using
|
|
6
|
+
* SyncSagaCoordinator sync and 3-way graft merge strategy.
|
|
7
|
+
* Projects merged branch snapshot onto the base branch physical worktree path.
|
|
8
|
+
*
|
|
9
|
+
* ## Terminology (matches standard git usage)
|
|
10
|
+
*
|
|
11
|
+
* * **base** branch / space — the branch currently checked out, the one being
|
|
12
|
+
* merged INTO (analogous to `ours` / `HEAD` in git)
|
|
13
|
+
* * **incoming** branch / space — the branch whose changes are being merged IN
|
|
14
|
+
* (analogous to `theirs` / the topic branch in git)
|
|
7
15
|
*/
|
|
8
16
|
|
|
9
17
|
import path from 'node:path';
|
|
@@ -11,7 +19,8 @@ import fs from 'node:fs/promises';
|
|
|
11
19
|
|
|
12
20
|
import { clone, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
13
21
|
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
14
|
-
import { putInSpace, getLatestAddrs, } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';
|
|
22
|
+
import { putInSpace, getLatestAddrs, persistTransformResult, registerNewIbGib } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';
|
|
23
|
+
import { rel8 } from '@ibgib/ts-gib/dist/V1/transforms/rel8.mjs';
|
|
15
24
|
import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs';
|
|
16
25
|
import { SyncPeerInnerspace_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
|
|
17
26
|
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
|
|
@@ -23,43 +32,52 @@ import { bootstrapVcsMetaspace } from '../../bootstrap/node-bootstrap.mjs';
|
|
|
23
32
|
import { B2tFSBranchIbGib_V1 } from '../../engine/branch/branch-types.mjs';
|
|
24
33
|
import { getOrCreateBranchSpace } from '../../engine/branch/branch-space-helper.mjs';
|
|
25
34
|
import { B2tFSItemIbGib_V1, B2TFS_CHILD_ITEM_REL8N_NAME } from '../../engine/item/item-types.mjs';
|
|
26
|
-
import { writeB2tFSItemToFS, getIbGibWithMetaspaceFallback } from '../../engine/item/item-helper.mjs';
|
|
35
|
+
import { writeB2tFSItemToFS, getIbGibWithMetaspaceFallback, reifyB2tFSHierarchy } from '../../engine/item/item-helper.mjs';
|
|
27
36
|
import { getB2tFSIndexIbGib, updateB2tFSIndexIbGib } from '../../engine/index/index-helper.mjs';
|
|
28
37
|
import { GLOBAL_LOG_A_LOT } from '../../vcs-gib-constants.mjs';
|
|
38
|
+
import { logBranchState, logItemState, logCheckpoint, logAddr, logAddrs } from '../../test/test-helpers.mjs';
|
|
39
|
+
|
|
29
40
|
|
|
30
41
|
const lcFile = `[merge-cmd]`;
|
|
31
42
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
32
43
|
|
|
33
44
|
export interface MergeCmdOpts {
|
|
34
|
-
|
|
45
|
+
/** The incoming branch name — the branch whose changes will be merged in. */
|
|
46
|
+
incomingBranchName?: string;
|
|
35
47
|
targetDir?: string;
|
|
36
48
|
vcsFolderName?: string;
|
|
37
49
|
quiet?: boolean;
|
|
50
|
+
/** When true, emit diagnostic checkpoint logging (useful in tests). */
|
|
51
|
+
diagLog?: boolean;
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
export interface MergeCmdResult {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
/** The base (current/active) branch name — merged into. */
|
|
56
|
+
baseBranch: string;
|
|
57
|
+
/** The incoming branch name — merged from. */
|
|
58
|
+
incomingBranch: string;
|
|
59
|
+
baseSpaceId: string;
|
|
60
|
+
incomingSpaceId: string;
|
|
45
61
|
mergedBranchAddr?: string;
|
|
46
62
|
worktreePath: string;
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
export async function executeMergeCmd({
|
|
50
|
-
|
|
66
|
+
incomingBranchName,
|
|
51
67
|
targetDir = process.cwd(),
|
|
52
68
|
vcsFolderName = '.vcsgib',
|
|
53
69
|
quiet = false,
|
|
70
|
+
diagLog = false,
|
|
54
71
|
}: MergeCmdOpts = {}): Promise<MergeCmdResult> {
|
|
55
72
|
const lc = `${lcFile}[${executeMergeCmd.name}]`;
|
|
73
|
+
const diag = (label: string) => { if (diagLog) logCheckpoint(`merge-cmd: ${label}`); };
|
|
56
74
|
try {
|
|
57
75
|
if (logalot) {
|
|
58
76
|
console.log(`${lc} starting... (I: 4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f)`);
|
|
59
77
|
}
|
|
60
78
|
|
|
61
|
-
const
|
|
62
|
-
if (!
|
|
79
|
+
const trimmedIncomingBranch = incomingBranchName?.trim();
|
|
80
|
+
if (!trimmedIncomingBranch) {
|
|
63
81
|
throw new Error(`Branch name is required for merge (E: 5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a)`);
|
|
64
82
|
}
|
|
65
83
|
|
|
@@ -83,10 +101,10 @@ export async function executeMergeCmd({
|
|
|
83
101
|
throw new Error(`Repository index B2tFSIndexIbGib_V1 not found in localSpace (E: 7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c)`);
|
|
84
102
|
}
|
|
85
103
|
|
|
86
|
-
const
|
|
104
|
+
const baseBranchName = indexIbGib.data?.activeBranch || 'main';
|
|
87
105
|
|
|
88
|
-
if (
|
|
89
|
-
throw new Error(`Cannot merge branch '${
|
|
106
|
+
if (baseBranchName === trimmedIncomingBranch) {
|
|
107
|
+
throw new Error(`Cannot merge branch '${trimmedIncomingBranch}' into itself (E: 8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d)`);
|
|
90
108
|
}
|
|
91
109
|
|
|
92
110
|
// 2. Fetch all registered branch ibgibs
|
|
@@ -109,72 +127,79 @@ export async function executeMergeCmd({
|
|
|
109
127
|
}
|
|
110
128
|
}
|
|
111
129
|
|
|
112
|
-
// Resolve
|
|
113
|
-
const
|
|
114
|
-
(b) => b?.data?.name ===
|
|
130
|
+
// Resolve base branch node & incoming branch node
|
|
131
|
+
const baseBranchIbGib = branchIbGibs.findLast(
|
|
132
|
+
(b) => b?.data?.name === baseBranchName,
|
|
115
133
|
);
|
|
116
|
-
if (!
|
|
117
|
-
throw new Error(`
|
|
134
|
+
if (!baseBranchIbGib) {
|
|
135
|
+
throw new Error(`Base branch '${baseBranchName}' not found in repository (E: 9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e)`);
|
|
118
136
|
}
|
|
119
137
|
|
|
120
|
-
const
|
|
121
|
-
(b) => b?.data?.name ===
|
|
138
|
+
const incomingBranchIbGib = branchIbGibs.findLast(
|
|
139
|
+
(b) => b?.data?.name === trimmedIncomingBranch,
|
|
122
140
|
);
|
|
123
141
|
|
|
124
|
-
if (!
|
|
125
|
-
throw new Error(`Branch '${
|
|
142
|
+
if (!incomingBranchIbGib) {
|
|
143
|
+
throw new Error(`Branch '${trimmedIncomingBranch}' does not exist (E: 0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f)`);
|
|
126
144
|
}
|
|
127
145
|
|
|
128
|
-
// 3. Resolve
|
|
129
|
-
const
|
|
146
|
+
// 3. Resolve base branch space & incoming branch space
|
|
147
|
+
const baseSpaceRes = await getOrCreateBranchSpace({
|
|
130
148
|
metaspace,
|
|
131
149
|
vcsPath,
|
|
132
|
-
branchName:
|
|
150
|
+
branchName: baseBranchName,
|
|
133
151
|
});
|
|
134
|
-
const
|
|
152
|
+
const baseSpace = baseSpaceRes.space;
|
|
135
153
|
|
|
136
|
-
const
|
|
154
|
+
const incomingSpaceRes = await getOrCreateBranchSpace({
|
|
137
155
|
metaspace,
|
|
138
156
|
vcsPath,
|
|
139
|
-
branchName:
|
|
157
|
+
branchName: trimmedIncomingBranch,
|
|
140
158
|
});
|
|
141
|
-
const
|
|
159
|
+
const incomingSpace = incomingSpaceRes.space;
|
|
142
160
|
|
|
143
|
-
await putInSpace({ space:
|
|
144
|
-
await putInSpace({ space:
|
|
161
|
+
await putInSpace({ space: baseSpace, ibGib: baseBranchIbGib });
|
|
162
|
+
await putInSpace({ space: incomingSpace, ibGib: incomingBranchIbGib });
|
|
145
163
|
|
|
146
|
-
// Resolve latest branch tip inside
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
const
|
|
164
|
+
// Resolve latest branch tip inside incomingSpace (in case commits occurred on incoming branch)
|
|
165
|
+
const incomingBranchTjpAddr = incomingBranchIbGib.rel8ns?.tjp?.at(0) || getIbGibAddr({ ibGib: incomingBranchIbGib });
|
|
166
|
+
const latestIncomingBranchRes = await getLatestAddrs({ space: incomingSpace, addrs: [incomingBranchTjpAddr] });
|
|
167
|
+
const latestIncomingBranchAddr = (latestIncomingBranchRes?.data as any)?.latestAddrs?.[0] || getIbGibAddr({ ibGib: incomingBranchIbGib });
|
|
150
168
|
|
|
151
|
-
const
|
|
152
|
-
addr:
|
|
153
|
-
space:
|
|
169
|
+
const latestIncomingBranchIbGib = (await getIbGibWithMetaspaceFallback({
|
|
170
|
+
addr: latestIncomingBranchAddr,
|
|
171
|
+
space: incomingSpace,
|
|
154
172
|
metaspace,
|
|
155
|
-
})) as B2tFSBranchIbGib_V1 ||
|
|
173
|
+
})) as B2tFSBranchIbGib_V1 || incomingBranchIbGib;
|
|
156
174
|
|
|
157
|
-
const
|
|
175
|
+
const incomingRootAddr = latestIncomingBranchIbGib.rel8ns?.b2tfs_item?.at(-1);
|
|
158
176
|
|
|
159
|
-
if (!
|
|
160
|
-
throw new Error(`
|
|
177
|
+
if (!incomingRootAddr) {
|
|
178
|
+
throw new Error(`Incoming branch '${trimmedIncomingBranch}' has no valid root item address (E: 3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e)`);
|
|
161
179
|
}
|
|
162
|
-
const
|
|
163
|
-
addr:
|
|
164
|
-
space:
|
|
180
|
+
const incomingRootItem = await getIbGibWithMetaspaceFallback({
|
|
181
|
+
addr: incomingRootAddr,
|
|
182
|
+
space: incomingSpace,
|
|
165
183
|
metaspace,
|
|
166
184
|
});
|
|
167
|
-
if (!
|
|
168
|
-
throw new Error(`
|
|
185
|
+
if (!incomingRootItem) {
|
|
186
|
+
throw new Error(`Incoming root item '${incomingRootAddr}' not found in incoming space (E: 4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f)`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (diagLog) {
|
|
190
|
+
diag('resolving branches & spaces');
|
|
191
|
+
await logBranchState({ label: 'baseBranch (main)', branchIbGib: baseBranchIbGib, space: baseSpace });
|
|
192
|
+
await logBranchState({ label: 'incomingBranch (feature-merge)', branchIbGib: incomingBranchIbGib, space: incomingSpace });
|
|
193
|
+
await logItemState({ label: 'incomingRootItem', itemIbGib: incomingRootItem, space: incomingSpace });
|
|
169
194
|
}
|
|
170
195
|
|
|
171
|
-
// 4. Setup SyncPeerInnerspace and SyncSagaCoordinator syncing
|
|
196
|
+
// 4. Setup SyncPeerInnerspace and SyncSagaCoordinator syncing incoming branch space into base branch space
|
|
172
197
|
const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
|
|
173
198
|
await peer.initialized;
|
|
174
199
|
await peer.initializeOpts({
|
|
175
200
|
localMetaspace: metaspace,
|
|
176
|
-
localSpace:
|
|
177
|
-
receiverSpace:
|
|
201
|
+
localSpace: incomingSpace,
|
|
202
|
+
receiverSpace: baseSpace,
|
|
178
203
|
receiverCoordinator: new SyncSagaCoordinator(),
|
|
179
204
|
receiverMetaspace: metaspace,
|
|
180
205
|
});
|
|
@@ -182,31 +207,74 @@ export async function executeMergeCmd({
|
|
|
182
207
|
const senderCoordinator = new SyncSagaCoordinator();
|
|
183
208
|
const syncSaga = await senderCoordinator.sync({
|
|
184
209
|
peer,
|
|
185
|
-
localSpace:
|
|
210
|
+
localSpace: incomingSpace,
|
|
186
211
|
metaspace,
|
|
187
|
-
domainIbGibs: [
|
|
212
|
+
domainIbGibs: [incomingRootItem],
|
|
188
213
|
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
189
214
|
graftPreference: GraftPreference.receiver,
|
|
190
215
|
});
|
|
191
216
|
|
|
192
217
|
await syncSaga.done;
|
|
193
218
|
|
|
194
|
-
// 5.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
// 5. Reify the base branch filesystem hierarchy.
|
|
220
|
+
// After sync, any child timelines (files or subfolders) that were merged/advanced
|
|
221
|
+
// in baseSpace will have newer tips. reifyB2tFSHierarchy bubbles all updated child tips
|
|
222
|
+
// up through the folder DAG, evolving parents in-place and returning the newly reified root item.
|
|
223
|
+
const currentBaseRootItemAddr = baseBranchIbGib.rel8ns?.b2tfs_item?.at(-1);
|
|
224
|
+
if (!currentBaseRootItemAddr) {
|
|
225
|
+
throw new Error(`Base branch '${baseBranchName}' has no root item address (E: 6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d)`);
|
|
226
|
+
}
|
|
198
227
|
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
space:
|
|
228
|
+
const reifyRes = await reifyB2tFSHierarchy({
|
|
229
|
+
rootItemAddr: currentBaseRootItemAddr,
|
|
230
|
+
space: baseSpace,
|
|
202
231
|
metaspace,
|
|
203
|
-
})
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const reifiedRootItem = reifyRes.reifiedRootItem;
|
|
235
|
+
const reifiedRootAddr = getIbGibAddr({ ibGib: reifiedRootItem });
|
|
236
|
+
|
|
237
|
+
if (diagLog) {
|
|
238
|
+
diag('after reification');
|
|
239
|
+
logAddr('currentBaseRootItemAddr', currentBaseRootItemAddr);
|
|
240
|
+
logAddr('reifiedRootAddr', reifiedRootAddr);
|
|
241
|
+
console.log(`[merge-cmd] reification hasChanges:`, reifyRes.hasChanges);
|
|
242
|
+
console.log(`[merge-cmd] reifiedAddrsMap:`, JSON.stringify(reifyRes.reifiedAddrsMap));
|
|
243
|
+
}
|
|
204
244
|
|
|
205
|
-
|
|
245
|
+
// 5b. Evolve the base branch ibgib to point at the reified root item tip.
|
|
246
|
+
// The sync engine does not update branch ibgibs — branches live in
|
|
247
|
+
// their own space and are never domain ibgibs in the sync. We advance
|
|
248
|
+
// the branch pointer to the reified root item.
|
|
249
|
+
let mergedBranchAddr: string = getIbGibAddr({ ibGib: baseBranchIbGib });
|
|
250
|
+
if (reifyRes.hasChanges && reifiedRootAddr !== currentBaseRootItemAddr) {
|
|
251
|
+
if (diagLog) {
|
|
252
|
+
console.log(`[merge-cmd] Evolving base branch: root item changing from ${currentBaseRootItemAddr} -> ${reifiedRootAddr}`);
|
|
253
|
+
}
|
|
254
|
+
const resRel8Branch = await rel8({
|
|
255
|
+
src: baseBranchIbGib,
|
|
256
|
+
rel8nsToReplaceByAddr: {
|
|
257
|
+
b2tfs_item: [{ oldAddr: currentBaseRootItemAddr, newAddr: reifiedRootAddr }],
|
|
258
|
+
},
|
|
259
|
+
dna: true,
|
|
260
|
+
nCounter: true,
|
|
261
|
+
});
|
|
262
|
+
const evolvedBranchIbGib = resRel8Branch.newIbGib;
|
|
263
|
+
await persistTransformResult({ resTransform: resRel8Branch, space: baseSpace });
|
|
264
|
+
await registerNewIbGib({ ibGib: evolvedBranchIbGib, space: baseSpace });
|
|
265
|
+
mergedBranchAddr = getIbGibAddr({ ibGib: evolvedBranchIbGib });
|
|
266
|
+
if (diagLog) {
|
|
267
|
+
console.log(`[merge-cmd] Base branch evolved to addr: ${mergedBranchAddr}`);
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
if (diagLog) {
|
|
271
|
+
console.log(`[merge-cmd] Base branch root item unchanged (${currentBaseRootItemAddr})`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
206
274
|
|
|
207
275
|
// Update indexIbGib to reference new merged branch node
|
|
208
276
|
await updateB2tFSIndexIbGib({
|
|
209
|
-
space:
|
|
277
|
+
space: baseSpace,
|
|
210
278
|
metaspace,
|
|
211
279
|
indexIbGib,
|
|
212
280
|
rel8nsToUpdate: {
|
|
@@ -215,28 +283,38 @@ export async function executeMergeCmd({
|
|
|
215
283
|
vcsPath,
|
|
216
284
|
});
|
|
217
285
|
|
|
286
|
+
const mergedRootItemAddr = reifiedRootAddr;
|
|
287
|
+
|
|
288
|
+
if (diagLog) {
|
|
289
|
+
diag('projecting onto disk');
|
|
290
|
+
logAddr('mergedRootItemAddr', mergedRootItemAddr);
|
|
291
|
+
}
|
|
218
292
|
|
|
219
293
|
// 6. Project merged branch snapshot files onto physical worktree disk
|
|
220
|
-
const isDefaultBranch =
|
|
294
|
+
const isDefaultBranch = baseBranchName === 'main';
|
|
221
295
|
const worktreePath = isDefaultBranch
|
|
222
296
|
? repoRoot
|
|
223
|
-
: path.join(repoRoot, 'b',
|
|
297
|
+
: path.join(repoRoot, 'b', baseBranchName);
|
|
224
298
|
|
|
225
299
|
await fs.mkdir(worktreePath, { recursive: true });
|
|
226
300
|
|
|
227
301
|
if (mergedRootItemAddr) {
|
|
228
302
|
const mergedRootItem = await getIbGibWithMetaspaceFallback({
|
|
229
303
|
addr: mergedRootItemAddr,
|
|
230
|
-
space:
|
|
304
|
+
space: baseSpace,
|
|
231
305
|
metaspace,
|
|
232
306
|
}) as B2tFSItemIbGib_V1;
|
|
233
307
|
|
|
308
|
+
if (diagLog) {
|
|
309
|
+
await logItemState({ label: 'mergedRootItem to write', itemIbGib: mergedRootItem, space: baseSpace });
|
|
310
|
+
}
|
|
311
|
+
|
|
234
312
|
if (mergedRootItem) {
|
|
235
313
|
if (mergedRootItem.data?.fsType === 'file') {
|
|
236
314
|
await writeB2tFSItemToFS({
|
|
237
315
|
item: mergedRootItem,
|
|
238
316
|
destPath: worktreePath,
|
|
239
|
-
space:
|
|
317
|
+
space: baseSpace,
|
|
240
318
|
metaspace,
|
|
241
319
|
});
|
|
242
320
|
} else {
|
|
@@ -244,7 +322,7 @@ export async function executeMergeCmd({
|
|
|
244
322
|
for (const childAddr of childAddrs) {
|
|
245
323
|
const childItem = await getIbGibWithMetaspaceFallback({
|
|
246
324
|
addr: childAddr,
|
|
247
|
-
space:
|
|
325
|
+
space: baseSpace,
|
|
248
326
|
metaspace,
|
|
249
327
|
}) as B2tFSItemIbGib_V1;
|
|
250
328
|
|
|
@@ -252,7 +330,7 @@ export async function executeMergeCmd({
|
|
|
252
330
|
await writeB2tFSItemToFS({
|
|
253
331
|
item: childItem,
|
|
254
332
|
destPath: worktreePath,
|
|
255
|
-
space:
|
|
333
|
+
space: baseSpace,
|
|
256
334
|
metaspace,
|
|
257
335
|
});
|
|
258
336
|
}
|
|
@@ -262,16 +340,16 @@ export async function executeMergeCmd({
|
|
|
262
340
|
}
|
|
263
341
|
|
|
264
342
|
if (!quiet) {
|
|
265
|
-
console.log(`Successfully merged branch '${
|
|
343
|
+
console.log(`Successfully merged branch '${trimmedIncomingBranch}' into '${baseBranchName}' (I: 1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a)`);
|
|
266
344
|
console.log(` Worktree projection: ${worktreePath}`);
|
|
267
345
|
}
|
|
268
346
|
|
|
269
347
|
return {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
mergedBranchAddr
|
|
348
|
+
baseBranch: baseBranchName,
|
|
349
|
+
incomingBranch: trimmedIncomingBranch,
|
|
350
|
+
baseSpaceId: baseSpaceRes.spaceId,
|
|
351
|
+
incomingSpaceId: incomingSpaceRes.spaceId,
|
|
352
|
+
mergedBranchAddr,
|
|
275
353
|
worktreePath,
|
|
276
354
|
};
|
|
277
355
|
} catch (error) {
|