ReviewOS

also looking at this

reviewos/reviewos.org

fix(merge): git replay takes --advance, not flags it never had

#3
Merged glennmichael123 wants to merge fix/rebase-merge-replay into main
1 file +11 -14
app/Actions/Pull/apply.tsmodified+11-14
Changes to app/Actions/Pull/apply.ts
@@ -81,27 +81,24 @@ export async function performMerge(path: string, input: MergeInput): Promise<Mer
8181 * entirely on objects, with no index and no checkout. Anything else would mean
8282 * checking out a copy of the repository on every merge.
8383 *
84 * It is asked to print the ref update rather than apply it, so the ref still
85 * moves through the same guarded `update-ref` as the other strategies. Some git
86 * versions apply the update themselves by default, which would skip that guard
87 * and let a merge overwrite a push that arrived a moment earlier.
84 * `--advance` names the branch the commits are for, and replay only ever
85 * *prints* the ref update - it never applies one - so the ref still moves
86 * through the same guarded `update-ref` as the other strategies. The commits
87 * are built on the branch's current tip; when that tip is no longer the
88 * baseSha the rules were checked against, the guard below refuses, which is
89 * the same answer the other strategies give to a push that arrived mid-merge.
8890 */
8991async function performRebase(
9092 path: string,
9193 input: MergeInput,
9294 env: Record<string, string>,
9395): Promise<MergeResult> {
94 const range = [
95 `--onto=${input.baseSha}`,
96 `--ref=refs/heads/${input.base}`,
96 const replayed = await runGit(path, [
97 'replay',
98 '--advance',
99 `refs/heads/${input.base}`,
97100 `${input.baseSha}..${input.headSha}`,
98 ]
99
100 let replayed = await runGit(path, ['replay', '--ref-action=print', ...range], { env })
101
102 // Older git has no --ref-action because printing was all it ever did.
103 if (!replayed.ok && /unknown option|unrecognized/i.test(replayed.stderr))
104 replayed = await runGit(path, ['replay', ...range], { env })
101 ], { env })
105102
106103 if (!replayed.ok)
107104 return { ok: false, error: replayed.stderr.trim() || 'the branch could not be replayed onto the base' }