From a8747c4f86a1947250aa86ab1869fb4bde10bb71 Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Tue, 10 Dec 2019 00:06:26 -0500 Subject: [PATCH] fix: verify is branch is up to date by comparing remote and local HEAD --- lib/git.js | 38 ++++---------------------------------- test/git.test.js | 31 ++++++++----------------------- 2 files changed, 12 insertions(+), 57 deletions(-) diff --git a/lib/git.js b/lib/git.js index 563b477424..dc75018ac3 100644 --- a/lib/git.js +++ b/lib/git.js @@ -69,33 +69,6 @@ async function getBranches(repositoryUrl, execaOpts) { .filter(Boolean); } -/** - * Verify if the `ref` is in the direct history of a given branch. - * - * @param {String} ref The reference to look for. - * @param {String} branch The branch for which to check if the `ref` is in history. - * @param {Object} [execaOpts] Options to pass to `execa`. - * - * @return {Boolean} `true` if the reference is in the history of the current branch, falsy otherwise. - */ -async function isRefInHistory(ref, branch, execaOpts) { - if (!(await isRefExists(branch, execaOpts))) { - return false; - } - - try { - await execa('git', ['merge-base', '--is-ancestor', ref, branch], execaOpts); - return true; - } catch (error) { - if (error.exitCode === 1) { - return false; - } - - debug(error); - throw error; - } -} - /** * Verify if the `ref` exits * @@ -310,12 +283,10 @@ async function verifyBranchName(branch, execaOpts) { * @return {Boolean} `true` is the HEAD of the current local branch is the same as the HEAD of the remote branch, falsy otherwise. */ async function isBranchUpToDate(repositoryUrl, branch, execaOpts) { - const {stdout: remoteHead} = await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOpts); - try { - return await isRefInHistory(remoteHead.match(/^(?\w+)?/)[1], branch, execaOpts); - } catch (error) { - debug(error); - } + return ( + (await getGitHead(execaOpts)) === + (await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOpts)).stdout.match(/^(?\w+)?/)[1] + ); } /** @@ -355,7 +326,6 @@ module.exports = { getTags, getCommits, getBranches, - isRefInHistory, isRefExists, fetch, fetchNotes, diff --git a/test/git.test.js b/test/git.test.js index 09c2180262..781994f65b 100644 --- a/test/git.test.js +++ b/test/git.test.js @@ -2,7 +2,6 @@ import test from 'ava'; import tempy from 'tempy'; import { getTagHead, - isRefInHistory, isRefExists, fetch, getGitHead, @@ -125,23 +124,6 @@ test('Fetch all tags on a repository with a detached head from branch', async t t.deepEqual((await getTags('master', {cwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0', 'v2.0.0'].sort()); }); -test('Verify if the commit `sha` is in the direct history of the current branch', async t => { - // Create a git repository, set the current working directory at the root of the repo - const {cwd} = await gitRepo(); - // Add commits to the master branch - const commits = await gitCommits(['First'], {cwd}); - // Create the new branch 'other-branch' from master - await gitCheckout('other-branch', true, {cwd}); - // Add commits to the 'other-branch' branch - const otherCommits = await gitCommits(['Second'], {cwd}); - await gitCheckout('master', false, {cwd}); - - t.true(await isRefInHistory(commits[0].hash, 'master', {cwd})); - t.falsy(await isRefInHistory(otherCommits[0].hash, 'master', {cwd})); - t.falsy(await isRefInHistory(otherCommits[0].hash, 'missing-branch', {cwd})); - await t.throwsAsync(isRefInHistory('non-existant-sha', 'master', {cwd})); -}); - test('Verify if a branch exists', async t => { // Create a git repository, set the current working directory at the root of the repo const {cwd} = await gitRepo(); @@ -299,13 +281,16 @@ test('Return falsy if repository is not up to date', async t => { t.falsy(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); }); -test('Return "true" if local repository is ahead', async t => { - const {cwd, repositoryUrl} = await gitRepo(true); - await gitCommits(['First'], {cwd}); - await gitPush(repositoryUrl, 'master', {cwd}); +test('Return falsy if detached head repository is not up to date', async t => { + let {cwd, repositoryUrl} = await gitRepo(); + + const [commit] = await gitCommits(['First'], {cwd}); await gitCommits(['Second'], {cwd}); + await gitPush(repositoryUrl, 'master', {cwd}); + cwd = await gitDetachedHead(repositoryUrl, commit.hash); + await fetch(repositoryUrl, 'master', 'master', {cwd}); - t.true(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); + t.falsy(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); }); test('Get a commit note', async t => {