|
4 | 4 |
|
5 | 5 | const assert = require("assert") |
6 | 6 | const fs = require("fs") |
| 7 | +const { execSync } = require("child_process") |
7 | 8 |
|
8 | 9 | const obj1 = { |
9 | 10 | "a": "b", |
@@ -103,75 +104,93 @@ const prefix = "" // "test/.tmp-described.off/" |
103 | 104 | const rewrittenListFile = fs.readFileSync(prefix + ".git/stacked-rebase/rewritten-list", { encoding: "utf-8" }) |
104 | 105 | console.log({ rewrittenListFile }) |
105 | 106 |
|
106 | | -// const rewrittenLists = rewrittenListFile |
107 | | -// .split("\n---\n") |
108 | | -// .map(lines => lines.split("\n")) |
109 | | -// .map(lines => lines.slice(1)) // remove $1 |
110 | | -// .filter(lines => lines.length && lines.every(line => line.length)) // remove empty "amend" |
111 | | -// console.log({ lists: rewrittenLists }); |
| 107 | +/** |
| 108 | + * $1 (amend/rebase) |
| 109 | + */ |
| 110 | +const extraOperatorLineCount = 1 |
112 | 111 |
|
113 | 112 | const rewrittenLists = rewrittenListFile |
114 | 113 | .split("\n\n") |
115 | 114 | .map(lists => lists.split("\n")) |
116 | 115 | .map(list => list[list.length - 1] === "" ? list.slice(0, -1) : list) |
117 | 116 | // .slice(0, -1) |
118 | | - .filter(list => list.length) |
119 | | - .map(list => list.map(line => line.split(" "))) |
120 | | - .map(list => Object.fromEntries(list)) |
121 | | -console.log({ rewrittenLists }); |
122 | | - |
123 | | -const reducedRewrittenLists = rewrittenLists |
124 | | - // .map(list => (reducePath(list), list)) |
125 | | - .map(list => reducePath(list)) |
126 | | - |
127 | | -console.log({ reducedRewrittenLists }); |
| 117 | + .filter(list => list.length > extraOperatorLineCount) |
| 118 | + .map(list => ({ |
| 119 | + type: list[0], |
| 120 | + mapping: Object.fromEntries( |
| 121 | + list.slice(1).map(line => line.split(" ")) |
| 122 | + ) |
| 123 | + }) |
| 124 | + ) |
| 125 | + // .map(list => Object.fromEntries(list)) |
| 126 | +console.log("rewrittenLists", rewrittenLists) |
| 127 | + |
| 128 | +let prev = [] |
| 129 | +let mergedReducedRewrittenLists = [] |
| 130 | +for (const list of rewrittenLists) { |
| 131 | + if (list.type === "amend") { |
| 132 | + prev.push(list) |
| 133 | + } else if (list.type === "rebase") { |
| 134 | + /** |
| 135 | + * merging time |
| 136 | + */ |
| 137 | + for (const amend of prev) { |
| 138 | + assert.equal(Object.keys(amend.mapping).length, 1) |
| 139 | + |
| 140 | + const [key, value] = Object.entries(amend.mapping)[0] |
| 141 | + |
| 142 | + /** |
| 143 | + * (try to) merge |
| 144 | + */ |
| 145 | + if (key in list.mapping) { |
| 146 | + if (value === list.mapping[key]) { |
| 147 | + // pointless |
| 148 | + continue |
| 149 | + } else { |
| 150 | + throw new Error( |
| 151 | + `NOT IMPLEMENTED - identical key in 'amend' and 'rebase', but different values.` |
| 152 | + + `(key = "${key}", amend's value = "${value}", rebase's value = "${list.mapping[key]}")` |
| 153 | + ) |
| 154 | + } |
| 155 | + } else { |
| 156 | + if (Object.values(list.mapping).includes(key)) { |
| 157 | + /** |
| 158 | + * add the single new entry of amend's mapping into rebase's mapping. |
| 159 | + * it will get `reducePath`'d later. |
| 160 | + */ |
| 161 | + Object.assign(list.mapping, amend.mapping) |
| 162 | + } else { |
| 163 | + throw new Error( |
| 164 | + "NOT IMPLEMENTED - neither key nor value of 'amend' was included in the 'rebase'." |
| 165 | + + "could be that we missed the ordering, or when we call 'reducePath', or something else." |
| 166 | + ) |
| 167 | + } |
| 168 | + } |
| 169 | + } |
128 | 170 |
|
129 | | -const last = reducedRewrittenLists[reducedRewrittenLists.length - 1] |
130 | | -const lastVals = Object.values(last).reverse() |
131 | | -console.log({ lastVals }); |
| 171 | + prev = [] |
| 172 | + reducePath(list.mapping) |
| 173 | + mergedReducedRewrittenLists.push(list) |
| 174 | + } else { |
| 175 | + throw new Error(`invalid list type (got "${list.type}")`) |
| 176 | + } |
| 177 | +} |
132 | 178 | /** |
133 | | - * compare with |
134 | | - * git log --pretty=format:"%H" |
| 179 | + * TODO handle multiple rebases |
| 180 | + * or, multiple separate files for each new rebase, |
| 181 | + * since could potentially lose some info if skipping partial steps? |
135 | 182 | */ |
136 | 183 |
|
137 | | -/** |
138 | | - * ayo lol, prolly found a bug in git -- the output in |
139 | | - * rewritten-list, or /dev/stdin, after the rebase is done, |
140 | | - * is not fully complete -- it doesn't correctly print the SHAs |
141 | | - * that got changed while the rebase was paused, |
142 | | - * e.g. commit --amend while paused by "edit" or "break" commands. |
143 | | - * |
144 | | - * thus, at least until we report it and confirm it's actually a bug |
145 | | - * and not intended this way, |
146 | | - * we can get the desired output for ourselves |
147 | | - * by merging all the rewrittenLists! |
148 | | - * |
149 | | - */ |
| 184 | +console.log("mergedReducedRewrittenLists", mergedReducedRewrittenLists) |
150 | 185 |
|
151 | | -/** |
152 | | - * TODO verify keys/values are not identical in a bad way |
153 | | - */ |
154 | | -const merge = (A, B) => ({ |
155 | | - ...A, |
156 | | - ...B |
157 | | -}) |
| 186 | +const b4 = Object.keys(mergedReducedRewrittenLists[0].mapping) |
| 187 | +const after = Object.values(mergedReducedRewrittenLists[0].mapping) |
158 | 188 |
|
159 | | -const mergedReducedRewrittenLists = reducedRewrittenLists.reduce((acc, curr) => reducePath(merge(acc, curr)), {}) |
| 189 | +fs.writeFileSync("b4", b4.join("\n") + "\n") |
| 190 | +fs.writeFileSync("after", after.join("\n") + "\n") |
160 | 191 |
|
161 | | -console.log({ mergedReducedRewrittenLists }); |
162 | | -const vals = Object.values(mergedReducedRewrittenLists).reverse() |
163 | | -console.log({ vals }); |
| 192 | +const N = after.length |
| 193 | +console.log({ N }) |
164 | 194 |
|
165 | | -/** |
166 | | - * it fixes the above issues! |
167 | | - * |
168 | | - * but wait! we cannot just merge like this, |
169 | | - * because when we take the values, |
170 | | - * the commits whom were not the full list (and only 1 commit remap, because --amend, |
171 | | - * or not full rebase up till the initial branch (TODO need to confirm the 2nd case)), |
172 | | - * end up being in the wrong place (they end up either in the start or the end). |
173 | | - * |
174 | | - * the problem is that we don't know __when__ the rewrite of the commit happened. |
175 | | - * TODO need to track that as well? |
176 | | - * |
177 | | - */ |
| 195 | +execSync(`git log --pretty=format:"%H" | head -n ${N} | tac - > curr`) |
| 196 | +execSync(`diff -us curr after`, { stdio: "inherit" }) |
0 commit comments