From 9ab4b5d4e9efece2a3881f0cd77cdb19b7e9f181 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Thu, 29 Aug 2019 10:30:17 +0200
Subject: [PATCH] feat: refactor pr.canRebase => !pr.isModified (#4385)

---
 lib/platform/azure/azure-helper.ts            |  2 +-
 lib/platform/bitbucket-server/index.ts        | 25 ++++-----------
 lib/platform/bitbucket-server/utils.ts        |  2 +-
 lib/platform/bitbucket/index.ts               | 26 ++++-----------
 lib/platform/github/index.ts                  | 27 ++++++++--------
 lib/platform/gitlab/index.ts                  |  7 ++--
 lib/workers/branch/index.js                   |  2 +-
 lib/workers/branch/parent.js                  | 10 +++---
 lib/workers/pr/index.js                       |  2 +-
 lib/workers/repository/finalise/prune.js      |  2 +-
 .../repository/onboarding/branch/rebase.js    |  2 +-
 lib/workers/repository/onboarding/pr/index.js |  2 +-
 .../__snapshots__/azure-helper.spec.ts.snap   |  8 ++---
 .../__snapshots__/index.spec.ts.snap          | 32 +++++++++----------
 .../__snapshots__/index.spec.ts.snap          | 10 +++---
 .../github/__snapshots__/index.spec.ts.snap   | 21 ++++++------
 test/platform/github/index.spec.ts            |  6 ++--
 .../gitlab/__snapshots__/index.spec.ts.snap   | 11 ++++---
 test/workers/branch/index.spec.js             | 18 +++++------
 test/workers/branch/parent.spec.js            | 10 +++---
 .../pr/__snapshots__/index.spec.js.snap       |  4 +--
 test/workers/pr/index.spec.js                 |  8 ++---
 .../workers/repository/finalise/prune.spec.js |  4 +--
 .../onboarding/branch/rebase.spec.js          |  6 ++--
 .../repository/onboarding/pr/index.spec.js    |  4 ++-
 25 files changed, 117 insertions(+), 134 deletions(-)

diff --git a/lib/platform/azure/azure-helper.ts b/lib/platform/azure/azure-helper.ts
index a65d38cb61..6c16e4e2a7 100644
--- a/lib/platform/azure/azure-helper.ts
+++ b/lib/platform/azure/azure-helper.ts
@@ -236,7 +236,7 @@ export function getRenovatePRFormat(azurePr: {
     pr.isConflicted = true;
   }
 
-  pr.canRebase = true;
+  pr.isModified = false;
 
   return pr;
 }
diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts
index 768c2e91d1..8f15c9cca2 100644
--- a/lib/platform/bitbucket-server/index.ts
+++ b/lib/platform/bitbucket-server/index.ts
@@ -785,7 +785,7 @@ export async function createPr(
   const pr = {
     id: prInfoRes.body.id,
     displayNumber: `Pull Request #${prInfoRes.body.id}`,
-    canRebase: true,
+    isModified: false,
     ...utils.prInfo(prInfoRes.body),
   };
 
@@ -817,6 +817,7 @@ export async function getPr(prNo: number, refreshCache?: boolean) {
     reviewers: res.body.reviewers.map(
       (r: { user: { name: any } }) => r.user.name
     ),
+    isModified: false,
   };
 
   pr.version = updatePrVersion(pr.number, pr.version);
@@ -837,32 +838,20 @@ export async function getPr(prNo: number, refreshCache?: boolean) {
     if (prCommits.totalCount === 1) {
       if (global.gitAuthor) {
         const commitAuthorEmail = prCommits.values[0].author.emailAddress;
-        if (commitAuthorEmail === global.gitAuthor.email) {
+        if (commitAuthorEmail !== global.gitAuthor.email) {
           logger.debug(
             { prNo },
-            '1 commit matches configured gitAuthor so can rebase'
+            'PR is modified: 1 commit but not by configured gitAuthor'
           );
-          pr.canRebase = true;
-        } else {
-          logger.debug(
-            { prNo },
-            '1 commit and not by configured gitAuthor so cannot rebase'
-          );
-          pr.canRebase = false;
+          pr.isModified = true;
         }
-      } else {
-        logger.debug(
-          { prNo },
-          '1 commit and no configured gitAuthor so can rebase'
-        );
-        pr.canRebase = true;
       }
     } else {
       logger.debug(
         { prNo },
-        `${prCommits.totalCount} commits so cannot rebase`
+        `PR is modified: Found ${prCommits.totalCount} commits`
       );
-      pr.canRebase = false;
+      pr.isModified = true;
     }
   }
 
diff --git a/lib/platform/bitbucket-server/utils.ts b/lib/platform/bitbucket-server/utils.ts
index 5c7a33431f..b77e41e3b9 100644
--- a/lib/platform/bitbucket-server/utils.ts
+++ b/lib/platform/bitbucket-server/utils.ts
@@ -19,7 +19,7 @@ export function prInfo(pr: any) {
     title: pr.title,
     state: prStateMapping[pr.state],
     createdAt: pr.createdDate,
-    canRebase: false,
+    isModified: true,
   };
 }
 
diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts
index 5daac06a82..fff83a9339 100644
--- a/lib/platform/bitbucket/index.ts
+++ b/lib/platform/bitbucket/index.ts
@@ -552,7 +552,7 @@ export async function createPr(
   const pr = {
     number: prInfo.id,
     displayNumber: `Pull Request #${prInfo.id}`,
-    canRebase: true,
+    isModified: false,
   };
   // istanbul ignore if
   if (config.prList) {
@@ -587,6 +587,7 @@ export async function getPr(prNo: number) {
   const res: any = {
     displayNumber: `Pull Request #${pr.id}`,
     ...utils.prInfo(pr),
+    isModified: false,
   };
 
   if (utils.prStates.open.includes(pr.state)) {
@@ -603,35 +604,22 @@ export async function getPr(prNo: number) {
     // istanbul ignore if
     if (size === undefined) {
       logger.warn({ prNo, url, body }, 'invalid response so can rebase');
-      res.canRebase = true;
     } else if (size === 1) {
       if (global.gitAuthor) {
         const author = addrs.parseOneAddress(
           body.values[0].author.raw
         ) as addrs.ParsedMailbox;
-        if (author.address === global.gitAuthor.email) {
+        if (author.address !== global.gitAuthor.email) {
           logger.debug(
             { prNo },
-            '1 commit matches configured gitAuthor so can rebase'
+            'PR is modified: 1 commit but not by configured gitAuthor'
           );
-          res.canRebase = true;
-        } else {
-          logger.debug(
-            { prNo },
-            '1 commit and not by configured gitAuthor so cannot rebase'
-          );
-          res.canRebase = false;
+          res.isModified = true;
         }
-      } else {
-        logger.debug(
-          { prNo },
-          '1 commit and no configured gitAuthor so can rebase'
-        );
-        res.canRebase = true;
       }
     } else {
-      logger.debug({ prNo }, `${size} commits so cannot rebase`);
-      res.canRebase = false;
+      logger.debug({ prNo }, `PR is modified: Found ${size} commits`);
+      res.isModified = true;
     }
   }
   if (await branchExists(pr.source.branch.name)) {
diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts
index 48fa7fe937..be95b54da7 100644
--- a/lib/platform/github/index.ts
+++ b/lib/platform/github/index.ts
@@ -36,7 +36,7 @@ interface Pr {
   sha: string;
 
   sourceRepo: string;
-  canRebase: boolean;
+  isModified: boolean;
 }
 
 interface LocalRepoConfig {
@@ -1216,7 +1216,7 @@ export async function createPr(
       urls.homepage
     );
   }
-  pr.canRebase = true;
+  pr.isModified = false;
   return pr;
 }
 
@@ -1324,7 +1324,7 @@ async function getOpenPrs() {
             // Check against gitAuthor
             const commitAuthorEmail = pr.commits.nodes[0].commit.author.email;
             if (commitAuthorEmail === global.gitAuthor.email) {
-              pr.canRebase = true;
+              pr.isModified = false;
             } else {
               logger.trace(
                 {
@@ -1333,14 +1333,14 @@ async function getOpenPrs() {
                   commitAuthorEmail,
                   gitAuthorEmail: global.gitAuthor.email,
                 },
-                'PR canRebase=false: last committer has different email to the bot'
+                'PR isModified=true: last committer has different email to the bot'
               );
-              pr.canRebase = false;
+              pr.isModified = true;
             }
           } else {
             // assume the author is us
             // istanbul ignore next
-            pr.canRebase = true;
+            pr.isModified = false;
           }
         } else {
           // assume we can't rebase if more than 1
@@ -1349,9 +1349,9 @@ async function getOpenPrs() {
               branchName,
               prNo,
             },
-            'PR canRebase=false: PR has more than one commit'
+            'PR isModified=true: PR has more than one commit'
           );
-          pr.canRebase = false;
+          pr.isModified = true;
         }
         pr.isStale = false;
         if (pr.mergeStateStatus === 'BEHIND') {
@@ -1480,6 +1480,7 @@ export async function getPr(prNo: number) {
   // Harmonise PR values
   pr.displayNumber = `Pull Request #${pr.number}`;
   if (pr.state === 'open') {
+    pr.isModified = true;
     pr.branchName = pr.head ? pr.head.ref : undefined;
     pr.sha = pr.head ? pr.head.sha : undefined;
     if (pr.mergeable === true) {
@@ -1501,7 +1502,7 @@ export async function getPr(prNo: number) {
             { prNo },
             '1 commit matches configured gitAuthor so can rebase'
           );
-          pr.canRebase = true;
+          pr.isModified = false;
         } else {
           logger.trace(
             {
@@ -1509,16 +1510,16 @@ export async function getPr(prNo: number) {
               commitAuthorEmail,
               gitAuthorEmail: global.gitAuthor.email,
             },
-            'PR canRebase=false: 1 commit and not by configured gitAuthor so cannot rebase'
+            'PR isModified=true: 1 commit and not by configured gitAuthor so cannot rebase'
           );
-          pr.canRebase = false;
+          pr.isModified = true;
         }
       } else {
         logger.debug(
           { prNo },
           '1 commit and no configured gitAuthor so can rebase'
         );
-        pr.canRebase = true;
+        pr.isModified = false;
       }
     } else {
       // Check if only one author of all commits
@@ -1551,7 +1552,7 @@ export async function getPr(prNo: number) {
         }
       );
       if (remainingCommits.length <= 1) {
-        pr.canRebase = true;
+        pr.isModified = false;
       }
     }
     const baseCommitSHA = await getBaseCommitSHA();
diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts
index 5bb7b797dc..906043aa8d 100644
--- a/lib/platform/gitlab/index.ts
+++ b/lib/platform/gitlab/index.ts
@@ -709,7 +709,7 @@ export async function createPr(
   pr.number = pr.iid;
   pr.branchName = branchName;
   pr.displayNumber = `Merge Request #${pr.iid}`;
-  pr.canRebase = true;
+  pr.isModified = false;
   // istanbul ignore if
   if (config.prList) {
     config.prList.push(pr);
@@ -729,6 +729,7 @@ export async function getPr(iid: number) {
   pr.body = pr.description;
   pr.isStale = pr.diverged_commits_count > 0;
   pr.state = pr.state === 'opened' ? 'open' : pr.state;
+  pr.isModified = true;
   if (pr.merge_status === 'cannot_be_merged') {
     logger.debug('pr cannot be merged');
     pr.canMerge = false;
@@ -750,13 +751,13 @@ export async function getPr(iid: number) {
       branch && branch.commit ? branch.commit.author_email : null;
     // istanbul ignore if
     if (branchCommitEmail === config.email) {
-      pr.canRebase = true;
+      pr.isModified = false;
     } else {
       logger.debug(
         { branchCommitEmail, configEmail: config.email, iid: pr.iid },
         'Last committer to branch does not match bot email, so PR cannot be rebased.'
       );
-      pr.canRebase = false;
+      pr.isModified = true;
     }
   } catch (err) {
     logger.debug({ err }, 'Error getting PR branch');
diff --git a/lib/workers/branch/index.js b/lib/workers/branch/index.js
index 562c230a11..fcbfd0b491 100644
--- a/lib/workers/branch/index.js
+++ b/lib/workers/branch/index.js
@@ -123,7 +123,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
           throw new Error('repository-changed');
         }
         if (
-          !branchPr.canRebase ||
+          branchPr.isModified ||
           (branchPr.targetBranch &&
             branchPr.targetBranch !== branchConfig.baseBranch)
         ) {
diff --git a/lib/workers/branch/parent.js b/lib/workers/branch/parent.js
index 5d5089157b..efaeed44d5 100644
--- a/lib/workers/branch/parent.js
+++ b/lib/workers/branch/parent.js
@@ -50,12 +50,12 @@ async function getParentBranch(config) {
     if (isBranchStale) {
       logger.info(`Branch is stale and needs rebasing`);
       // We can rebase the branch only if no PR or PR can be rebased
-      if (!pr || pr.canRebase) {
+      if (!pr || !pr.isModified) {
         return { parentBranch: undefined };
       }
       // TODO: Warn here so that it appears in PR body
       logger.info('Cannot rebase branch');
-      return { parentBranch: branchName, canRebase: false };
+      return { parentBranch: branchName, isModified: true };
     }
   }
 
@@ -63,11 +63,11 @@ async function getParentBranch(config) {
   if (pr && pr.isConflicted) {
     logger.debug('PR is conflicted');
 
-    if (pr.canRebase) {
+    if (!pr.isModified) {
       logger.info(`Branch is not mergeable and needs rebasing`);
       if (!config.rebaseConflictedPrs) {
         logger.info('rebaseConflictedPrs is disabled');
-        return { parentBranch: branchName, canRebase: true };
+        return { parentBranch: branchName, isModified: false };
       }
       // Setting parentBranch back to undefined means that we'll use the default branch
       return { parentBranch: undefined };
@@ -77,5 +77,5 @@ async function getParentBranch(config) {
     logger.info(`Branch is not mergeable but can't be rebased`);
   }
   logger.debug(`Branch does not need rebasing`);
-  return { parentBranch: branchName, canRebase: true };
+  return { parentBranch: branchName, isModified: false };
 }
diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.js
index ed33ee1212..573fbd00c0 100644
--- a/lib/workers/pr/index.js
+++ b/lib/workers/pr/index.js
@@ -412,7 +412,7 @@ async function checkAutoMerge(pr, config) {
       return false;
     }
     // Check if it's been touched
-    if (!pr.canRebase) {
+    if (pr.isModified) {
       logger.info('PR is ready for automerge but has been modified');
       return false;
     }
diff --git a/lib/workers/repository/finalise/prune.js b/lib/workers/repository/finalise/prune.js
index 6d9bf904bf..8e9f2203ba 100644
--- a/lib/workers/repository/finalise/prune.js
+++ b/lib/workers/repository/finalise/prune.js
@@ -12,7 +12,7 @@ async function cleanUpBranches(
     try {
       const pr = await platform.findPr(branchName, null, 'open');
       const branchPr = await platform.getBranchPr(branchName);
-      const skipAutoclose = branchPr && !branchPr.canRebase;
+      const skipAutoclose = branchPr && branchPr.isModified;
       if (pr && !skipAutoclose) {
         if (!pr.title.endsWith('- autoclosed')) {
           if (dryRun) {
diff --git a/lib/workers/repository/onboarding/branch/rebase.js b/lib/workers/repository/onboarding/branch/rebase.js
index 2eb960cf10..20141b2a0a 100644
--- a/lib/workers/repository/onboarding/branch/rebase.js
+++ b/lib/workers/repository/onboarding/branch/rebase.js
@@ -26,7 +26,7 @@ function getCommitMessage(config) {
 async function rebaseOnboardingBranch(config) {
   logger.debug('Checking if onboarding branch needs rebasing');
   const pr = await platform.getBranchPr(onboardingBranch);
-  if (!pr.canRebase) {
+  if (pr.isModified) {
     logger.info('Onboarding branch has been edited and cannot be rebased');
     return;
   }
diff --git a/lib/workers/repository/onboarding/pr/index.js b/lib/workers/repository/onboarding/pr/index.js
index ade8d8edcd..c05fa96f28 100644
--- a/lib/workers/repository/onboarding/pr/index.js
+++ b/lib/workers/repository/onboarding/pr/index.js
@@ -56,7 +56,7 @@ If you need any further assistance then you can also [request help here](${urls.
     prBody = prBody.replace('{{PACKAGE FILES}}\n', '');
   }
   let configDesc = '';
-  if (!existingPr || existingPr.canRebase) {
+  if (!(existingPr && existingPr.isModified)) {
     configDesc = getConfigDesc(config, packageFiles);
   } else {
     configDesc = `### Configuration\n\n:abcd: ${appName} has detected a custom config for this PR. Feel free to ask for [help](${urls.help}) if you have any doubts and would like it reviewed.\n\n`;
diff --git a/test/platform/azure/__snapshots__/azure-helper.spec.ts.snap b/test/platform/azure/__snapshots__/azure-helper.spec.ts.snap
index fd8b5ddd8b..fd991ce6c0 100644
--- a/test/platform/azure/__snapshots__/azure-helper.spec.ts.snap
+++ b/test/platform/azure/__snapshots__/azure-helper.spec.ts.snap
@@ -87,8 +87,8 @@ Array [
 exports[`platform/azure/helpers getRenovatePRFormat should be formated (closed v2) 1`] = `
 Object {
   "body": undefined,
-  "canRebase": true,
   "displayNumber": "Pull Request #undefined",
+  "isModified": false,
   "number": undefined,
   "state": "merged",
   "status": 3,
@@ -99,8 +99,8 @@ Object {
 exports[`platform/azure/helpers getRenovatePRFormat should be formated (closed) 1`] = `
 Object {
   "body": undefined,
-  "canRebase": true,
   "displayNumber": "Pull Request #undefined",
+  "isModified": false,
   "number": undefined,
   "state": "closed",
   "status": 2,
@@ -111,9 +111,9 @@ Object {
 exports[`platform/azure/helpers getRenovatePRFormat should be formated (isConflicted) 1`] = `
 Object {
   "body": undefined,
-  "canRebase": true,
   "displayNumber": "Pull Request #undefined",
   "isConflicted": true,
+  "isModified": false,
   "mergeStatus": 2,
   "number": undefined,
   "state": "open",
@@ -124,8 +124,8 @@ Object {
 exports[`platform/azure/helpers getRenovatePRFormat should be formated (not closed) 1`] = `
 Object {
   "body": undefined,
-  "canRebase": true,
   "displayNumber": "Pull Request #undefined",
+  "isModified": false,
   "number": undefined,
   "state": "open",
   "status": 1,
diff --git a/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap b/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
index ea6651cbfb..f010522505 100644
--- a/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
+++ b/test/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
@@ -501,8 +501,8 @@ Object {
   "body": "* Line 1
 * Line 2",
   "branchName": "userName1/pullRequest5",
-  "canRebase": false,
   "createdAt": 1547853840016,
+  "isModified": true,
   "number": 5,
   "state": "open",
   "targetBranch": "master",
@@ -547,10 +547,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -714,10 +714,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": false,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -736,10 +736,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -758,10 +758,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": false,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -845,10 +845,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -894,9 +894,9 @@ exports[`platform/bitbucket-server endpoint with no path getPr() gets a closed P
 Object {
   "body": undefined,
   "branchName": undefined,
-  "canRebase": false,
   "createdAt": undefined,
   "displayNumber": "Pull Request #undefined",
+  "isModified": false,
   "isStale": false,
   "number": undefined,
   "reviewers": Array [],
@@ -963,8 +963,8 @@ Array [
     "body": "* Line 1
 * Line 2",
     "branchName": "userName1/pullRequest5",
-    "canRebase": false,
     "createdAt": 1547853840016,
+    "isModified": true,
     "number": 5,
     "state": "open",
     "targetBranch": "master",
@@ -1983,8 +1983,8 @@ Object {
   "body": "* Line 1
 * Line 2",
   "branchName": "userName1/pullRequest5",
-  "canRebase": false,
   "createdAt": 1547853840016,
+  "isModified": true,
   "number": 5,
   "state": "open",
   "targetBranch": "master",
@@ -2029,10 +2029,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -2196,10 +2196,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": false,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -2218,10 +2218,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -2240,10 +2240,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": false,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -2327,10 +2327,10 @@ Object {
 * Line 2",
   "branchName": "userName1/pullRequest5",
   "canMerge": false,
-  "canRebase": true,
   "createdAt": 1547853840016,
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "reviewers": Array [
@@ -2376,9 +2376,9 @@ exports[`platform/bitbucket-server endpoint with path getPr() gets a closed PR 1
 Object {
   "body": undefined,
   "branchName": undefined,
-  "canRebase": false,
   "createdAt": undefined,
   "displayNumber": "Pull Request #undefined",
+  "isModified": false,
   "isStale": false,
   "number": undefined,
   "reviewers": Array [],
@@ -2445,8 +2445,8 @@ Array [
     "body": "* Line 1
 * Line 2",
     "branchName": "userName1/pullRequest5",
-    "canRebase": false,
     "createdAt": 1547853840016,
+    "isModified": true,
     "number": 5,
     "state": "open",
     "targetBranch": "master",
diff --git a/test/platform/bitbucket/__snapshots__/index.spec.ts.snap b/test/platform/bitbucket/__snapshots__/index.spec.ts.snap
index 8e42c66191..6f095e089f 100644
--- a/test/platform/bitbucket/__snapshots__/index.spec.ts.snap
+++ b/test/platform/bitbucket/__snapshots__/index.spec.ts.snap
@@ -144,10 +144,10 @@ Object {
   "body": "summary",
   "branchName": "branch",
   "canMerge": true,
-  "canRebase": true,
   "createdAt": "2018-07-02T07:02:25.275030+00:00",
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "state": "open",
@@ -161,10 +161,10 @@ Object {
   "body": "summary",
   "branchName": "branch",
   "canMerge": true,
-  "canRebase": false,
   "createdAt": "2018-07-02T07:02:25.275030+00:00",
   "displayNumber": "Pull Request #3",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 3,
   "state": "open",
@@ -178,10 +178,10 @@ Object {
   "body": "summary",
   "branchName": "branch",
   "canMerge": true,
-  "canRebase": true,
   "createdAt": "2018-07-02T07:02:25.275030+00:00",
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "state": "open",
@@ -195,10 +195,10 @@ Object {
   "body": "summary",
   "branchName": "branch",
   "canMerge": true,
-  "canRebase": false,
   "createdAt": "2018-07-02T07:02:25.275030+00:00",
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": true,
   "isStale": false,
   "number": 5,
   "state": "open",
@@ -253,10 +253,10 @@ Object {
   "body": "summary",
   "branchName": "branch",
   "canMerge": true,
-  "canRebase": true,
   "createdAt": "2018-07-02T07:02:25.275030+00:00",
   "displayNumber": "Pull Request #5",
   "isConflicted": false,
+  "isModified": false,
   "isStale": false,
   "number": 5,
   "state": "open",
diff --git a/test/platform/github/__snapshots__/index.spec.ts.snap b/test/platform/github/__snapshots__/index.spec.ts.snap
index f022c4567e..7bf58d6ea3 100644
--- a/test/platform/github/__snapshots__/index.spec.ts.snap
+++ b/test/platform/github/__snapshots__/index.spec.ts.snap
@@ -38,8 +38,8 @@ Array [
 exports[`platform/github createPr() should create and return a PR object 1`] = `
 Object {
   "branchName": "some-branch",
-  "canRebase": true,
   "displayNumber": "Pull Request #123",
+  "isModified": false,
   "number": 123,
 }
 `;
@@ -83,8 +83,8 @@ Array [
 exports[`platform/github createPr() should use defaultBranch 1`] = `
 Object {
   "branchName": "some-branch",
-  "canRebase": true,
   "displayNumber": "Pull Request #123",
+  "isModified": false,
   "number": 123,
 }
 `;
@@ -170,13 +170,13 @@ Object {
     "sha": "1234",
   },
   "branchName": "somebranch",
-  "canRebase": true,
   "commits": 1,
   "deletions": 1,
   "displayNumber": "Pull Request #91",
   "head": Object {
     "ref": "somebranch",
   },
+  "isModified": false,
   "isStale": true,
   "number": 91,
   "sha": undefined,
@@ -211,9 +211,9 @@ exports[`platform/github getPr(prNo) should return PR from graphql result 1`] =
 Object {
   "branchName": "renovate/jest-monorepo",
   "canMerge": false,
-  "canRebase": true,
   "displayNumber": "Pull Request #2500",
   "isConflicted": true,
+  "isModified": false,
   "isStale": true,
   "number": 2500,
   "state": "open",
@@ -241,10 +241,10 @@ Object {
     "sha": "1234",
   },
   "branchName": undefined,
-  "canRebase": true,
   "commits": 1,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": false,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
@@ -259,9 +259,9 @@ Object {
   },
   "branchName": undefined,
   "canMerge": true,
-  "canRebase": true,
   "commits": 1,
   "displayNumber": "Pull Request #1",
+  "isModified": false,
   "isStale": true,
   "mergeable": true,
   "number": 1,
@@ -276,10 +276,10 @@ Object {
     "sha": "1234",
   },
   "branchName": undefined,
-  "canRebase": false,
   "commits": 1,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": true,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
@@ -293,10 +293,10 @@ Object {
     "sha": "1234",
   },
   "branchName": undefined,
-  "canRebase": true,
   "commits": 2,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": false,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
@@ -310,10 +310,10 @@ Object {
     "sha": "1234",
   },
   "branchName": undefined,
-  "canRebase": true,
   "commits": 1,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": false,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
@@ -327,10 +327,10 @@ Object {
     "sha": "1234",
   },
   "branchName": undefined,
-  "canRebase": true,
   "commits": 2,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": false,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
@@ -347,6 +347,7 @@ Object {
   "commits": 2,
   "displayNumber": "Pull Request #1",
   "isConflicted": true,
+  "isModified": true,
   "mergeable_state": "dirty",
   "number": 1,
   "sha": undefined,
diff --git a/test/platform/github/index.spec.ts b/test/platform/github/index.spec.ts
index 555a643888..7d63b3dbf2 100644
--- a/test/platform/github/index.spec.ts
+++ b/test/platform/github/index.spec.ts
@@ -1736,7 +1736,7 @@ describe('platform/github', () => {
           } as any)
       );
       const pr = await github.getPr(1234);
-      expect(pr.canRebase).toBe(true);
+      expect(pr.isModified).toBe(false);
       expect(pr).toMatchSnapshot();
     });
     it('should return a rebaseable PR if gitAuthor matches 1 commit', async () => {
@@ -1785,7 +1785,7 @@ describe('platform/github', () => {
           } as any)
       );
       const pr = await github.getPr(1234);
-      expect(pr.canRebase).toBe(true);
+      expect(pr.isModified).toBe(false);
       expect(pr).toMatchSnapshot();
     });
     it('should return a not rebaseable PR if gitAuthor does not match 1 commit', async () => {
@@ -1834,7 +1834,7 @@ describe('platform/github', () => {
           } as any)
       );
       const pr = await github.getPr(1234);
-      expect(pr.canRebase).toBe(false);
+      expect(pr.isModified).toBe(true);
       expect(pr).toMatchSnapshot();
     });
   });
diff --git a/test/platform/gitlab/__snapshots__/index.spec.ts.snap b/test/platform/gitlab/__snapshots__/index.spec.ts.snap
index 9db70e0fa2..f43a1aa9fc 100644
--- a/test/platform/gitlab/__snapshots__/index.spec.ts.snap
+++ b/test/platform/gitlab/__snapshots__/index.spec.ts.snap
@@ -30,10 +30,10 @@ Array [
 exports[`platform/gitlab createPr(branchName, title, body) returns the PR 1`] = `
 Object {
   "branchName": "some-branch",
-  "canRebase": true,
   "displayNumber": "Merge Request #12345",
   "id": 1,
   "iid": 12345,
+  "isModified": false,
   "number": 12345,
 }
 `;
@@ -59,10 +59,10 @@ Array [
 exports[`platform/gitlab createPr(branchName, title, body) uses default branch 1`] = `
 Object {
   "branchName": "some-branch",
-  "canRebase": true,
   "displayNumber": "Merge Request #12345",
   "id": 1,
   "iid": 12345,
+  "isModified": false,
   "number": 12345,
 }
 `;
@@ -138,11 +138,11 @@ Object {
   },
   "body": undefined,
   "branchName": "some-branch",
-  "canRebase": false,
   "commits": 1,
   "deletions": 1,
   "displayNumber": "Merge Request #91",
   "iid": 91,
+  "isModified": true,
   "isStale": false,
   "number": 91,
   "source_branch": "some-branch",
@@ -157,13 +157,13 @@ Object {
   "body": "a merge request",
   "branchName": "some-branch",
   "canMerge": false,
-  "canRebase": true,
   "description": "a merge request",
   "displayNumber": "Merge Request #12345",
   "diverged_commits_count": 5,
   "id": 1,
   "iid": 12345,
   "isConflicted": true,
+  "isModified": false,
   "isStale": true,
   "merge_status": "cannot_be_merged",
   "number": 12345,
@@ -185,6 +185,7 @@ Object {
   "id": 1,
   "iid": 12345,
   "isConflicted": true,
+  "isModified": true,
   "isStale": true,
   "merge_status": "cannot_be_merged",
   "number": 12345,
@@ -200,12 +201,12 @@ Object {
   "body": "a merge request",
   "branchName": "some-branch",
   "canMerge": true,
-  "canRebase": false,
   "description": "a merge request",
   "displayNumber": "Merge Request #12345",
   "diverged_commits_count": 5,
   "id": 1,
   "iid": 12345,
+  "isModified": true,
   "isStale": true,
   "number": 12345,
   "source_branch": "some-branch",
diff --git a/test/workers/branch/index.spec.js b/test/workers/branch/index.spec.js
index 30dd138bd3..0c2bbc6971 100644
--- a/test/workers/branch/index.spec.js
+++ b/test/workers/branch/index.spec.js
@@ -93,7 +93,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValueOnce({
         state: 'open',
-        canRebase: true,
+        isModified: false,
       });
       await branchWorker.processBranch(config);
     });
@@ -144,7 +144,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValueOnce({
         state: 'merged',
-        canRebase: false,
+        isModified: true,
       });
       await expect(branchWorker.processBranch(config)).rejects.toThrow(
         /repository-changed/
@@ -155,7 +155,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValueOnce({
         state: 'open',
-        canRebase: false,
+        isModified: true,
         labels: ['rebase'],
       });
       const res = await branchWorker.processBranch(config);
@@ -166,7 +166,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValueOnce({
         state: 'open',
-        canRebase: false,
+        isModified: true,
       });
       const res = await branchWorker.processBranch(config);
       expect(res).toEqual('pr-edited');
@@ -176,7 +176,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValueOnce({
         state: 'open',
-        canRebase: true,
+        isModified: false,
         targetBranch: 'v6',
       });
       config.baseBranch = 'master';
@@ -406,7 +406,7 @@ describe('workers/branch', () => {
       platform.branchExists.mockReturnValueOnce(true);
       platform.getBranchPr.mockResolvedValueOnce({
         state: 'open',
-        canRebase: false,
+        isModified: true,
       });
       expect(
         await branchWorker.processBranch({ ...config, dryRun: true })
@@ -427,7 +427,7 @@ describe('workers/branch', () => {
         title: 'rebase!',
         state: 'open',
         body: `- [x] <!-- ${appSlug}-rebase -->`,
-        canRebase: false,
+        isModified: true,
       });
 
       schedule.isScheduledNow.mockReturnValueOnce(false);
@@ -458,7 +458,7 @@ describe('workers/branch', () => {
         title: 'rebase!',
         state: 'open',
         body: `- [x] <!-- ${appSlug}-rebase -->`,
-        canRebase: false,
+        isModified: true,
       });
 
       schedule.isScheduledNow.mockReturnValueOnce(false);
@@ -486,7 +486,7 @@ describe('workers/branch', () => {
         title: 'rebase!',
         state: 'open',
         body: `- [x] <!-- ${appSlug}-rebase -->`,
-        canRebase: false,
+        isModified: true,
       });
 
       schedule.isScheduledNow.mockReturnValueOnce(false);
diff --git a/test/workers/branch/parent.spec.js b/test/workers/branch/parent.spec.js
index 999c7f2bd7..70c3499562 100644
--- a/test/workers/branch/parent.spec.js
+++ b/test/workers/branch/parent.spec.js
@@ -39,7 +39,7 @@ describe('workers/branch/parent', () => {
       platform.branchExists.mockReturnValue(true);
       platform.getBranchPr.mockReturnValue({
         isConflicted: true,
-        canRebase: false,
+        isModified: true,
       });
       const res = await getParentBranch(config);
       expect(res.parentBranch).toBe(config.branchName);
@@ -49,7 +49,7 @@ describe('workers/branch/parent', () => {
       platform.branchExists.mockReturnValue(true);
       platform.getBranchPr.mockReturnValue({
         isConflicted: true,
-        canRebase: true,
+        isModified: false,
       });
       const res = await getParentBranch(config);
       expect(res.parentBranch).toBe(config.branchName);
@@ -74,7 +74,7 @@ describe('workers/branch/parent', () => {
     it('returns undefined if manual rebase by label', async () => {
       platform.branchExists.mockReturnValue(true);
       platform.getBranchPr.mockReturnValue({
-        canRebase: false,
+        isModified: true,
         labels: ['rebase'],
       });
       const res = await getParentBranch(config);
@@ -84,7 +84,7 @@ describe('workers/branch/parent', () => {
       platform.branchExists.mockReturnValue(true);
       platform.getBranchPr.mockReturnValue({
         isConflicted: true,
-        canRebase: true,
+        isModified: false,
       });
       const res = await getParentBranch(config);
       expect(res.parentBranch).toBeUndefined();
@@ -110,7 +110,7 @@ describe('workers/branch/parent', () => {
       platform.isBranchStale.mockReturnValueOnce(true);
       platform.getBranchPr.mockReturnValue({
         isConflicted: true,
-        canRebase: false,
+        isModified: true,
       });
       const res = await getParentBranch(config);
       expect(res.parentBranch).not.toBeUndefined();
diff --git a/test/workers/pr/__snapshots__/index.spec.js.snap b/test/workers/pr/__snapshots__/index.spec.js.snap
index 8885b22f7b..99b75d28a7 100644
--- a/test/workers/pr/__snapshots__/index.spec.js.snap
+++ b/test/workers/pr/__snapshots__/index.spec.js.snap
@@ -267,8 +267,8 @@ Object {
 ---
 
  - [ ] <!-- renovate-rebase -->If you want to rebase/retry this PR, check this box",
-  "canRebase": true,
   "displayNumber": "Existing PR",
+  "isModified": false,
   "title": "Update dependency dummy to v1.1.0",
 }
 `;
@@ -309,8 +309,8 @@ Object {
 ---
 
  - [ ] <!-- renovate-rebase -->If you want to rebase/retry this PR, check this box",
-  "canRebase": true,
   "displayNumber": "Existing PR",
+  "isModified": false,
   "title": "wrong",
 }
 `;
diff --git a/test/workers/pr/index.spec.js b/test/workers/pr/index.spec.js
index b44e3508d3..07ab4f89c0 100644
--- a/test/workers/pr/index.spec.js
+++ b/test/workers/pr/index.spec.js
@@ -61,7 +61,7 @@ describe('workers/pr', () => {
     });
     it('should automerge if enabled and pr is mergeable', async () => {
       config.automerge = true;
-      pr.canRebase = true;
+      pr.isModified = false;
       platform.getBranchStatus.mockReturnValueOnce('success');
       platform.mergePr.mockReturnValueOnce(true);
       await prWorker.checkAutoMerge(pr, config);
@@ -71,14 +71,14 @@ describe('workers/pr', () => {
       config.automerge = true;
       config.automergeType = 'pr-comment';
       config.automergeComment = '!merge';
-      pr.canRebase = true;
+      pr.isModified = false;
       platform.getBranchStatus.mockReturnValueOnce('success');
       await prWorker.checkAutoMerge(pr, config);
       expect(platform.ensureComment).toHaveBeenCalledTimes(1);
     });
     it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => {
       config.automerge = true;
-      pr.canRebase = false;
+      pr.isModified = true;
       platform.getBranchStatus.mockReturnValueOnce('success');
       await prWorker.checkAutoMerge(pr, config);
       expect(platform.mergePr).toHaveBeenCalledTimes(0);
@@ -110,7 +110,7 @@ describe('workers/pr', () => {
       title: 'Update dependency dummy to v1.1.0',
       body:
         'Some body<!-- Reviewable:start -->something<!-- Reviewable:end -->\n\n',
-      canRebase: true,
+      isModified: false,
     };
     beforeEach(() => {
       config = {
diff --git a/test/workers/repository/finalise/prune.spec.js b/test/workers/repository/finalise/prune.spec.js
index afe921eeff..5d0560d3a4 100644
--- a/test/workers/repository/finalise/prune.spec.js
+++ b/test/workers/repository/finalise/prune.spec.js
@@ -74,7 +74,7 @@ describe('workers/repository/finalise/prune', () => {
       platform.getAllRenovateBranches.mockReturnValueOnce(
         config.branchList.concat(['renovate/c'])
       );
-      platform.getBranchPr.mockReturnValueOnce({ canRebase: false });
+      platform.getBranchPr.mockReturnValueOnce({ isModified: true });
       platform.findPr.mockReturnValueOnce({ title: 'foo' });
       await cleanup.pruneStaleBranches(config, config.branchList);
       expect(platform.getAllRenovateBranches).toHaveBeenCalledTimes(1);
@@ -88,7 +88,7 @@ describe('workers/repository/finalise/prune', () => {
       platform.getAllRenovateBranches.mockReturnValueOnce(
         config.branchList.concat(['renovate/c'])
       );
-      platform.getBranchPr.mockReturnValueOnce({ canRebase: false });
+      platform.getBranchPr.mockReturnValueOnce({ isModified: true });
       platform.findPr.mockReturnValueOnce({ title: 'foo' });
       await cleanup.pruneStaleBranches(config, config.branchList);
       expect(platform.getAllRenovateBranches).toHaveBeenCalledTimes(1);
diff --git a/test/workers/repository/onboarding/branch/rebase.spec.js b/test/workers/repository/onboarding/branch/rebase.spec.js
index a7c2d326ab..956330c068 100644
--- a/test/workers/repository/onboarding/branch/rebase.spec.js
+++ b/test/workers/repository/onboarding/branch/rebase.spec.js
@@ -17,7 +17,7 @@ describe('workers/repository/onboarding/branch/rebase', () => {
     });
     it('does not rebase modified branch', async () => {
       platform.getBranchPr.mockReturnValueOnce({
-        canRebase: false,
+        isModified: true,
       });
       await rebaseOnboardingBranch(config);
       expect(platform.commitFilesToBranch).toHaveBeenCalledTimes(0);
@@ -28,7 +28,7 @@ describe('workers/repository/onboarding/branch/rebase', () => {
       platform.getFile.mockReturnValueOnce(contents); // package.json
       platform.getFile.mockReturnValueOnce(contents); // renovate.json
       platform.getBranchPr.mockReturnValueOnce({
-        canRebase: true,
+        isModified: false,
         isStale: false,
       });
       await rebaseOnboardingBranch(config);
@@ -37,7 +37,7 @@ describe('workers/repository/onboarding/branch/rebase', () => {
     it('rebases onboarding branch', async () => {
       platform.getBranchPr.mockReturnValueOnce({
         isStale: true,
-        canRebase: true,
+        isModified: false,
       });
       await rebaseOnboardingBranch(config);
       expect(platform.commitFilesToBranch).toHaveBeenCalledTimes(1);
diff --git a/test/workers/repository/onboarding/pr/index.spec.js b/test/workers/repository/onboarding/pr/index.spec.js
index a84a4996fb..03e224449b 100644
--- a/test/workers/repository/onboarding/pr/index.spec.js
+++ b/test/workers/repository/onboarding/pr/index.spec.js
@@ -39,7 +39,7 @@ describe('workers/repository/onboarding/pr', () => {
       platform.getBranchPr.mockReturnValue({
         title: 'Configure Renovate',
         body: createPrBody,
-        canRebase: true,
+        isModified: false,
       });
       await ensureOnboardingPr(config, packageFiles, branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
@@ -51,6 +51,7 @@ describe('workers/repository/onboarding/pr', () => {
         title: 'Configure Renovate',
         body: createPrBody,
         isConflicted: true,
+        isModified: true,
       });
       await ensureOnboardingPr(config, [], branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
@@ -61,6 +62,7 @@ describe('workers/repository/onboarding/pr', () => {
       platform.getBranchPr.mockReturnValue({
         title: 'Configure Renovate',
         body: createPrBody,
+        isModified: true,
       });
       await ensureOnboardingPr(config, [], branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
-- 
GitLab