UNPKG

mrgit

Version:

A tool for managing projects build using multiple repositories.

100 lines (88 loc) 3.58 kB
/** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md. */ 'use strict'; const UNMERGED_SYMBOLS = [ 'DD', // Deleted by both. 'UU', // Modified by both. 'AA', // Added by both. 'DU', // Deleted by us. 'AU', // Added by us. 'UD', // Deleted by them. 'UA' // Added by them. ]; const DELETE_STAGED_SYMBOL = 'D '; const DELETE_NOT_STAGED_SYMBOL = ' D'; const MODIFIED_STAGED_SYMBOL = 'M '; const MODIFIED_NOT_STAGED_SYMBOL = ' M'; const MODIFIED_STAGED_AND_NOT_STAGED_SYMBOL = 'MM'; const RENAMED_STAGED_SYMBOL = 'R '; const ADDED_STAGED_SYMBOL = 'A '; const UNTRACKED_SYMBOL = '??'; /** * @param {String} branchStatus An output returned by `git status --branch --porcelain` command. * @param {String} currentTag An output returned by `git describe --abbrev=0 --tags` command. * @returns {Object} data * @returns {Boolean} data.anythingToCommit Returns true if any changed file could be committed using command `git commit -a`. * @returns {String} data.branchOrTag Current branch or tag. * @returns {Number|null} data.behind Number of commits that branch is behind the remote upstream. * @returns {Number|null} data.ahead Number of commits that branch is ahead the remote upstream. * @returns {Array.<String>} data.added List of files created files (untracked files are tracked now). * @returns {Array.<String>} data.modified List of tracked files that have changed. * @returns {Array.<String>} data.deleted List of tracked files that have deleted. * @returns {Array.<String>} data.renamed List of tracked files that have moved (or renamed). * @returns {Array.<String>} data.unmerged List of tracked files that contain (unresolved) conflicts. * @returns {Array.<String>} data.untracked List of untracked files which won't be committed using command `git commit -a`. * @returns {Array.<String>} data.staged List of files that their changes are ready to commit. */ module.exports = function gitStatusParser( branchStatus, currentTag ) { const responseAsArray = branchStatus.split( '\n' ); const branchData = responseAsArray.shift(); const branch = branchData.split( '...' )[ 0 ].match( /## (.*)$/ )[ 1 ]; const tag = currentTag; const detachedHead = branch === 'HEAD (no branch)'; const added = filterFiles( [ ADDED_STAGED_SYMBOL ] ); const modified = filterFiles( [ MODIFIED_NOT_STAGED_SYMBOL, MODIFIED_STAGED_AND_NOT_STAGED_SYMBOL, DELETE_NOT_STAGED_SYMBOL ] ); const deleted = filterFiles( [ DELETE_STAGED_SYMBOL, DELETE_NOT_STAGED_SYMBOL ] ); const renamed = filterFiles( [ RENAMED_STAGED_SYMBOL ] ); const unmerged = filterFiles( UNMERGED_SYMBOLS ); const untracked = filterFiles( [ UNTRACKED_SYMBOL ] ); const staged = filterFiles( [ ADDED_STAGED_SYMBOL, DELETE_STAGED_SYMBOL, MODIFIED_STAGED_SYMBOL, MODIFIED_STAGED_AND_NOT_STAGED_SYMBOL, RENAMED_STAGED_SYMBOL ] ); let behind = branchData.match( /behind (\d+)/ ); let ahead = branchData.match( /ahead (\d+)/ ); if ( behind ) { behind = parseInt( behind[ 1 ], 10 ); } if ( ahead ) { ahead = parseInt( ahead[ 1 ], 10 ); } return { get anythingToCommit() { return [ added, modified, deleted, renamed, unmerged, staged ].some( collection => collection.length ); }, branch, tag, detachedHead, behind, ahead, added, modified, deleted, renamed, unmerged, untracked, staged }; function filterFiles( prefixes ) { return responseAsArray .filter( line => prefixes.some( prefix => prefix === line.substring( 0, 2 ) ) ) .map( line => line.slice( 2 ).trim() ); } };