-
-
Save joyeecheung/7889b89265dc66a6889f7f7167efb89f to your computer and use it in GitHub Desktop.
diff of diff, for double checking that you didn't mess up the backport you prepared
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Code is mostly written by ChatGPT | |
| // git checkout backport-require-esm-20-3 | |
| // git rev-list origin/v20.x-staging...HEAD | node match.js | |
| // node diff.js | |
| const { execSync } = require('child_process'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const os = require('os'); | |
| function getCommitDiff(commitHash) { | |
| try { | |
| return execSync( | |
| `git show --no-prefix --pretty=format: ${commitHash} | grep -v '^index ' | grep -v '^@@'`, | |
| { encoding: 'utf-8' } | |
| ); | |
| } catch (err) { | |
| console.error(`Error fetching diff for ${commitHash}:`, err.message); | |
| return null; | |
| } | |
| } | |
| let count = 0; | |
| function compareCommits(commit1, commit2) { | |
| const diff1 = getCommitDiff(commit1); | |
| const diff2 = getCommitDiff(commit2); | |
| if (!diff1 || !diff2) { | |
| console.error(`Skipping comparison for ${commit1} and ${commit2} due to missing diffs.`); | |
| return; | |
| } | |
| const tempDir = os.tmpdir(); | |
| const file1 = path.join(tempDir, `diff_${commit1}.patch`); | |
| const file2 = path.join(tempDir, `diff_${commit2}.patch`); | |
| fs.writeFileSync(file1, diff1); | |
| fs.writeFileSync(file2, diff2); | |
| const message = execSync(`git log -n 1 --pretty=format:%B ${commit1}`, { encoding: 'utf-8' }).trim(); | |
| const title = message.split('\n')[0]; | |
| try { | |
| const diffOutput = execSync(`diff -c ${file1} ${file2}`, { encoding: 'utf-8' }).trim(); | |
| if (!diffOutput) { | |
| console.log(`${title} is clean`); | |
| } | |
| } catch (err) { | |
| if (err.status === 1) { | |
| count++; | |
| const prefix = count.toString().padStart(4, '0'); | |
| const diff = err.stdout; | |
| const filename = `diffs/` + prefix + '-' + title.replaceAll(/\s/g, '-').replaceAll(/[:\/]/g, '') + '.diff' | |
| const output = `${message}\n-----------------\n${diff}`; | |
| fs.writeFileSync(filename, output, 'utf-8'); | |
| console.log(`Writing diff ${commit1.slice(0, 8)} and ${commit2.slice(0, 8)} to ${filename}`); | |
| } else { | |
| console.error(`Error running diff for ${commit1} and ${commit2}:`, err.message); | |
| } | |
| } finally { | |
| fs.unlinkSync(file1); | |
| fs.unlinkSync(file2); | |
| } | |
| } | |
| async function processCommits() { | |
| const commitPairs = JSON.parse(fs.readFileSync('commits.json', 'utf-8')).reverse(); | |
| for (const [commit1, commit2] of commitPairs) { | |
| compareCommits(commit1, commit2); | |
| } | |
| } | |
| fs.rmSync('./diffs', { recursive: true }); | |
| fs.mkdirSync('./diffs'); | |
| processCommits().catch(console.error); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Code is mostly written by ChatGPT | |
| // git checkout backport-require-esm-20-3 | |
| // git rev-list origin/v20.x-staging...HEAD | node match.js | |
| // node diff.js | |
| const { execSync, spawn } = require('child_process'); | |
| const readline = require('readline'); | |
| const fs = require('fs'); | |
| const rl = readline.createInterface({ | |
| input: process.stdin, | |
| output: process.stdout, | |
| terminal: false | |
| }); | |
| async function getCommitInfo(commitHash) { | |
| try { | |
| const commitMessage = execSync(`git log -n 1 --pretty=format:%B ${commitHash}`, { encoding: 'utf-8' }); | |
| const lines = commitMessage.split('\n').map(line => line.trim()).filter(line => line); | |
| if (lines.length === 0) return null; | |
| const title = lines[0]; | |
| const prUrlLine = lines.find(line => line.startsWith('PR-URL: https://github.com/nodejs/node/pull/')); | |
| const prMatch = prUrlLine ? prUrlLine.match(/PR-URL: https:\/\/github.com\/nodejs\/node\/pull\/(\d+)/) : null; | |
| const prNumber = prMatch ? prMatch[1] : null; | |
| return { commitHash, title, prNumber }; | |
| } catch (err) { | |
| console.error(`Error fetching commit info for ${commitHash}:`, err.message); | |
| return null; | |
| } | |
| } | |
| async function findMatchingCommitOnMain(title, prNumber) { | |
| return new Promise((resolve) => { | |
| const gitLog = spawn('git', ['log', 'origin/main', '--pretty=format:码%H%n%B']); | |
| const rl = readline.createInterface({ input: gitLog.stdout }); | |
| let mainCommitHash = null; | |
| let mainTitle = null; | |
| let mainPrNumber = null; | |
| let found = true; | |
| rl.on('line', (line) => { | |
| line = line.trim(); | |
| if (!line) return; | |
| if (line.startsWith('码')) { | |
| mainCommitHash = line.slice(1); | |
| mainTitle = null; | |
| mainPrNumber = null; | |
| return; | |
| } | |
| if (line === title) { | |
| mainTitle = line; | |
| return; | |
| } | |
| if (mainCommitHash && mainTitle && !mainPrNumber) { | |
| const mainPrMatch = line.match(/PR-URL: https:\/\/github.com\/nodejs\/node\/pull\/(\d+)/); | |
| if (mainPrMatch) { | |
| mainPrNumber = mainPrMatch[1]; | |
| if (mainPrNumber === prNumber) { | |
| found = true; | |
| rl.close(); | |
| resolve(mainCommitHash); | |
| } | |
| } | |
| } | |
| }); | |
| rl.on('close', () => { | |
| if (!found) { | |
| resolve(null); | |
| } | |
| gitLog.kill(); | |
| }); | |
| }); | |
| } | |
| (async () => { | |
| const data = []; | |
| for await (const line of rl) { | |
| const commitHash = line.trim(); | |
| if (!commitHash) continue; | |
| const commitInfo = await getCommitInfo(commitHash); | |
| if (!commitInfo || !commitInfo.title || !commitInfo.prNumber) { | |
| console.log(`${commitHash}: No matching info found`); | |
| continue; | |
| } | |
| const matchingCommit = await findMatchingCommitOnMain(commitInfo.title, commitInfo.prNumber); | |
| if (matchingCommit) { | |
| data.push([commitHash, matchingCommit]); | |
| console.log(commitHash, '->', matchingCommit); | |
| } else { | |
| console.log(`${commitHash}: No match found on main`); | |
| } | |
| } | |
| console.log('writting commits to commits.json'); | |
| fs.writeFileSync('commits.json', JSON.stringify(data, null, 2), 'utf-8'); | |
| })(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Code is mostly written by ChatGPT | |
| const { execSync } = require('child_process'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const os = require('os'); | |
| function getCommitDiff(commitHash) { | |
| try { | |
| return execSync( | |
| `git show --no-prefix --pretty=format: ${commitHash} | grep -v '^index ' | grep -v '^@@'`, | |
| { encoding: 'utf-8' } | |
| ); | |
| } catch (err) { | |
| console.error(`Error fetching diff for ${commitHash}:`, err.message); | |
| return null; | |
| } | |
| } | |
| let count = 0; | |
| function compareCommits(commit1, commit2) { | |
| const diff1 = getCommitDiff(commit1); | |
| const diff2 = getCommitDiff(commit2); | |
| if (!diff1 || !diff2) { | |
| console.error(`Skipping comparison for ${commit1} and ${commit2} due to missing diffs.`); | |
| return; | |
| } | |
| const tempDir = os.tmpdir(); | |
| const file1 = path.join(tempDir, `diff_${commit1}.patch`); | |
| const file2 = path.join(tempDir, `diff_${commit2}.patch`); | |
| fs.writeFileSync(file1, diff1); | |
| fs.writeFileSync(file2, diff2); | |
| const message = execSync(`git log -n 1 --pretty=format:%B ${commit1}`, { encoding: 'utf-8' }).trim(); | |
| const pr = message.match(/PR-URL: (.+)/)[1]; | |
| try { | |
| const diffOutput = execSync(`diff -c ${file1} ${file2}`, { encoding: 'utf-8' }).trim(); | |
| if (!diffOutput) { | |
| return `- ${pr}: no modifications\n`; | |
| } | |
| } catch (err) { | |
| if (err.status === 1) { | |
| return `- ${pr}: TODO\n`; | |
| } else { | |
| console.error(`Error running diff for ${commit1} and ${commit2}:`, err.message); | |
| } | |
| } finally { | |
| fs.unlinkSync(file1); | |
| fs.unlinkSync(file2); | |
| } | |
| } | |
| async function processCommits() { | |
| const commitPairs = JSON.parse(fs.readFileSync('commits.json', 'utf-8')).reverse(); | |
| let text = ''; | |
| for (const [commit1, commit2] of commitPairs) { | |
| const t = compareCommits(commit1, commit2); | |
| fs.writeSync(1, t); | |
| } | |
| fs.writeFileSync('./summary.md', text, 'utf-8'); | |
| } | |
| processCommits().catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment