Skip to content

Commit 4eaad65

Browse files
authored
feat(git-v8): preserve original author when backporting (#872)
1 parent ec6c6cb commit 4eaad65

File tree

3 files changed

+90
-13
lines changed

3 files changed

+90
-13
lines changed

components/git/v8.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,22 @@ export function builder(yargs) {
4444
describe: 'Bump V8 embedder version number or patch version',
4545
default: true
4646
})
47+
.option('gpg-sign', {
48+
alias: 'S',
49+
type: 'boolean',
50+
describe: 'GPG-sign commits',
51+
default: false
52+
})
53+
.option('preserve-original-author', {
54+
type: 'boolean',
55+
describe: 'Preserve original commit author and date',
56+
default: true
57+
})
4758
.option('squash', {
4859
type: 'boolean',
4960
describe:
50-
'If multiple commits are backported, squash them into one',
61+
'If multiple commits are backported, squash them into one. When ' +
62+
'`--squash` is passed, `--preserve-original-author` will be ignored',
5163
default: false
5264
});
5365
}
@@ -88,7 +100,7 @@ export function handler(argv) {
88100
input,
89101
spawnArgs: {
90102
cwd: options.nodeDir,
91-
stdio: input ? ['pipe', 'ignore', 'ignore'] : 'ignore'
103+
stdio: input ? ['pipe', 'inherit', 'inherit'] : 'inherit'
92104
}
93105
});
94106
};
@@ -97,7 +109,7 @@ export function handler(argv) {
97109
return forceRunAsync('git', args, {
98110
ignoreFailure: false,
99111
captureStdout: true,
100-
spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] }
112+
spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'inherit'] }
101113
});
102114
};
103115

lib/update-v8/backport.js

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer';
99
import { shortSha } from '../utils.js';
1010

1111
import { getCurrentV8Version } from './common.js';
12+
import { forceRunAsync } from '../run.js';
1213

1314
export async function checkOptions(options) {
1415
if (options.sha.length > 1 && options.squash) {
@@ -41,6 +42,8 @@ export function doBackport(options) {
4142
}
4243
}
4344
todo.push(commitSquashedBackport());
45+
} else if (options.preserveOriginalAuthor) {
46+
todo.push(cherryPickV8Commits(options));
4447
} else {
4548
todo.push(applyAndCommitPatches());
4649
}
@@ -76,18 +79,47 @@ function commitSquashedBackport() {
7679
};
7780
};
7881

79-
function commitPatch(patch) {
82+
const commitTask = (patch, extraArgs, trailers) => async(ctx) => {
83+
const messageTitle = formatMessageTitle([patch]);
84+
const messageBody = formatMessageBody(patch, false, trailers);
85+
await ctx.execGitNode('add', ['deps/v8']);
86+
await ctx.execGitNode('commit', [
87+
...ctx.gpgSign, ...extraArgs,
88+
'-m', messageTitle, '-m', messageBody
89+
]);
90+
};
91+
92+
function amendHEAD(patch) {
8093
return {
81-
title: 'Commit patch',
94+
title: 'Amend/commit',
8295
task: async(ctx) => {
83-
const messageTitle = formatMessageTitle([patch]);
84-
const messageBody = formatMessageBody(patch, false);
85-
await ctx.execGitNode('add', ['deps/v8']);
86-
await ctx.execGitNode('commit', ['-m', messageTitle, '-m', messageBody]);
96+
let coAuthor;
97+
if (patch.hadConflicts) {
98+
const getGitConfigEntry = async(configKey) => {
99+
const output = await forceRunAsync('git', ['config', configKey], {
100+
ignoreFailure: false,
101+
captureStdout: true,
102+
spawnArgs: { cwd: ctx.nodeDir }
103+
});
104+
return output.trim();
105+
};
106+
await ctx.execGitNode('am', [...ctx.gpgSign, '--continue']);
107+
coAuthor = `\nCo-authored-by: ${
108+
await getGitConfigEntry('user.name')} <${
109+
await getGitConfigEntry('user.email')}>`;
110+
}
111+
await commitTask(patch, ['--amend'], coAuthor)(ctx);
87112
}
88113
};
89114
}
90115

116+
function commitPatch(patch) {
117+
return {
118+
title: 'Commit patch',
119+
task: commitTask(patch)
120+
};
121+
}
122+
91123
function formatMessageTitle(patches) {
92124
const action =
93125
patches.some(patch => patch.hadConflicts) ? 'backport' : 'cherry-pick';
@@ -106,12 +138,12 @@ function formatMessageTitle(patches) {
106138
}
107139
}
108140

109-
function formatMessageBody(patch, prefixTitle) {
141+
function formatMessageBody(patch, prefixTitle, trailers = '') {
110142
const indentedMessage = patch.message.replace(/\n/g, '\n ');
111143
const body =
112144
'Original commit message:\n\n' +
113145
` ${indentedMessage}\n\n` +
114-
`Refs: https://github.com/v8/v8/commit/${patch.sha}`;
146+
`Refs: https://github.com/v8/v8/commit/${patch.sha}${trailers}`;
115147

116148
if (prefixTitle) {
117149
const action = patch.hadConflicts ? 'Backport' : 'Cherry-pick';
@@ -167,6 +199,15 @@ function applyAndCommitPatches() {
167199
};
168200
}
169201

202+
function cherryPickV8Commits() {
203+
return {
204+
title: 'Cherry-pick commit from V8 clone to deps/v8',
205+
task: (ctx, task) => {
206+
return task.newListr(ctx.patches.map(cherryPickV8CommitTask));
207+
}
208+
};
209+
}
210+
170211
function applyPatchTask(patch) {
171212
return {
172213
title: `Commit ${shortSha(patch.sha)}`,
@@ -190,10 +231,33 @@ function applyPatchTask(patch) {
190231
};
191232
}
192233

193-
async function applyPatch(ctx, task, patch) {
234+
function cherryPickV8CommitTask(patch) {
235+
return {
236+
title: `Commit ${shortSha(patch.sha)}`,
237+
task: (ctx, task) => {
238+
const todo = [
239+
{
240+
title: 'Cherry-pick',
241+
task: (ctx, task) => applyPatch(ctx, task, patch, 'am')
242+
}
243+
];
244+
if (ctx.bump !== false) {
245+
if (ctx.nodeMajorVersion < 9) {
246+
todo.push(incrementV8Version());
247+
} else {
248+
todo.push(incrementEmbedderVersion());
249+
}
250+
}
251+
todo.push(amendHEAD(patch));
252+
return task.newListr(todo);
253+
}
254+
};
255+
}
256+
257+
async function applyPatch(ctx, task, patch, method = 'apply') {
194258
try {
195259
await ctx.execGitNode(
196-
'apply',
260+
method,
197261
['-p1', '--3way', '--directory=deps/v8'],
198262
patch.data /* input */
199263
);

lib/update-v8/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function minor(options) {
2626
export async function backport(options) {
2727
const shouldStop = await checkOptions(options);
2828
if (shouldStop) return;
29+
options.gpgSign = options.gpgSign ? ['-S'] : [];
2930
const tasks = new Listr(
3031
[updateV8Clone(), doBackport(options)],
3132
getOptions(options)

0 commit comments

Comments
 (0)