Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

let squash merge detection be fuzzier #14

Merged
merged 1 commit into from
Nov 19, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions lib/commands/done.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

'use strict';

const debug = require('debug')('workflow:done');

const {
featureParent,
yesNo,
Expand All @@ -40,13 +42,21 @@ const {
inferRemote,
} = require('../common');

/**
* @param {string} diff
*/
/** @param {string} diff */
function stripIndexLines(diff) {
return diff.replace(/^index .*\n/gm, '');
}

/** @param {string} diff */
function stripLineNums(diff) {
return diff.replace(/^@@ .*\n/gm, '');
}

/** @param {{ message: string, hash: string }} commit */
function commitDescr({ message, hash }) {
return `[${hash.slice(0, 7)}] ${message}`;
}

/**
*
* @param {import('simple-git/promise').SimpleGit} git
Expand All @@ -59,13 +69,33 @@ async function findSquashedDiff(git, feature, parent) {
const diff = stripIndexLines(await git.diff([`${base}..${feature}`]));

const { all: commits } = await git.log({ from: base, to: parent });
for (const { hash, message } of commits) {
const show = await git.show([hash]);

/** @type {Map<typeof commits[0], string>} */
const cachedCommitDiffs = new Map();

for (const commit of commits) {
const show = await git.show([commit.hash]);
// strip off the commit msg at the beginning of the show
const commitDiff = stripIndexLines(show).replace(/^[\s\S]+?\ndiff/, 'diff');
if (commitDiff === diff) return `[${hash.slice(0, 7)}] ${message}`;
if (commitDiff === diff) return commitDescr(commit);
cachedCommitDiffs.set(commit, commitDiff);
}

debug("Couldn't find squashed diff on exact match; fudging line numbers");
const strippedDiff = stripLineNums(diff);

for (const commit of commits) {
let commitDiff = cachedCommitDiffs.get(commit);
if (!commitDiff) {
throw new Error(`Couldn't find cached commit diff for ${commit.hash}`);
}
commitDiff = stripLineNums(commitDiff);
if (commitDiff === strippedDiff) return commitDescr(commit);
}

debug('Failed to find squashed diff match for:');
debug(strippedDiff);

return null;
}

Expand Down