fix: verify is branch is up to date by comparing remote and local HEAD
This commit is contained in:
		
							parent
							
								
									9a1af4de44
								
							
						
					
					
						commit
						a8747c4f86
					
				
							
								
								
									
										38
									
								
								lib/git.js
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								lib/git.js
									
									
									
									
									
								
							| @ -69,33 +69,6 @@ async function getBranches(repositoryUrl, execaOpts) { | |||||||
|     .filter(Boolean); |     .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 |  * 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. |  * @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) { | async function isBranchUpToDate(repositoryUrl, branch, execaOpts) { | ||||||
|   const {stdout: remoteHead} = await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOpts); |   return ( | ||||||
|   try { |     (await getGitHead(execaOpts)) === | ||||||
|     return await isRefInHistory(remoteHead.match(/^(?<ref>\w+)?/)[1], branch, execaOpts); |     (await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOpts)).stdout.match(/^(?<ref>\w+)?/)[1] | ||||||
|   } catch (error) { |   ); | ||||||
|     debug(error); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -355,7 +326,6 @@ module.exports = { | |||||||
|   getTags, |   getTags, | ||||||
|   getCommits, |   getCommits, | ||||||
|   getBranches, |   getBranches, | ||||||
|   isRefInHistory, |  | ||||||
|   isRefExists, |   isRefExists, | ||||||
|   fetch, |   fetch, | ||||||
|   fetchNotes, |   fetchNotes, | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ import test from 'ava'; | |||||||
| import tempy from 'tempy'; | import tempy from 'tempy'; | ||||||
| import { | import { | ||||||
|   getTagHead, |   getTagHead, | ||||||
|   isRefInHistory, |  | ||||||
|   isRefExists, |   isRefExists, | ||||||
|   fetch, |   fetch, | ||||||
|   getGitHead, |   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()); |   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 => { | test('Verify if a branch exists', async t => { | ||||||
|   // Create a git repository, set the current working directory at the root of the repo
 |   // Create a git repository, set the current working directory at the root of the repo
 | ||||||
|   const {cwd} = await gitRepo(); |   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})); |   t.falsy(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test('Return "true" if local repository is ahead', async t => { | test('Return falsy if detached head repository is not up to date', async t => { | ||||||
|   const {cwd, repositoryUrl} = await gitRepo(true); |   let {cwd, repositoryUrl} = await gitRepo(); | ||||||
|   await gitCommits(['First'], {cwd}); |  | ||||||
|   await gitPush(repositoryUrl, 'master', {cwd}); |  | ||||||
|   await gitCommits(['Second'], {cwd}); |  | ||||||
| 
 | 
 | ||||||
|   t.true(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); |   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.falsy(await isBranchUpToDate(repositoryUrl, 'master', {cwd})); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test('Get a commit note', async t => { | test('Get a commit note', async t => { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user